Trying to use txt files for kakashi

testing
sgoudham 5 years ago
parent 9bea4a3f03
commit 08838fdabf

@ -8,15 +8,6 @@ client = commands.Bot(command_prefix='~')
# Instantiates a list for all the cogs
extensions = ['cogs.WaifuImages', 'cogs.FunCommands']
@client.command()
@commands.has_any_role('Hamothy')
async def users(ctx):
server_id = client.get_guild(663651584399507476)
await ctx.send(f"""Number of Members: {server_id.member_count}""")
# Calls the cogs
if __name__ == '__main__':
for ext in extensions:
@ -37,12 +28,6 @@ async def ping(ctx):
await ctx.send(f'Pong! {round(client.latency * 1000)}ms')
# @client.command(aliases=["Hug"])
# @commands.has_any_role('Hamothy')
# async def bruh(self, ctx):
# await self.bot.say("hugs {}".format(ctx.message.author.mention()))
# Bot ~roles command allows for an embed message about
@client.command()
@commands.has_any_role('Hamothy')
@ -96,3 +81,12 @@ async def on_command_error(ctx, error):
client.run('NzE2NzAxNjk5MTQ1NzI4MDk0.XtWFiw.KZrh9Tkp9vTY9JYSgZfpg2P4mlQ')
'''
@client.command()
@commands.has_any_role('Hamothy')
async def users(ctx):
server_id = client.get_guild(663651584399507476)
await ctx.send(f"""Number of Members: {server_id.member_count}""")
'''

@ -12,7 +12,8 @@ class Fun(commands.Cog):
@commands.command(aliases=['Attack'])
@commands.has_any_role('Hamothy', "izzy")
async def attack(self, ctx, target: discord.Member):
responses = [f"{target.mention} is stinky",
responses = [
f"{target.mention} is stinky",
f"{target.mention} is ugly",
f"{target.mention} has a gigantic nose",
f"{target.mention} gets no views on their tiktok",
@ -34,24 +35,46 @@ class Fun(commands.Cog):
f"I know this was made for me to insult but its kinda hard to be a hateful cunt like {target.mention} :star_struck::star_struck:",
f"#{target.mention}IsOverParty",
f"I hope {target.mention} drops dead with a curable disease that doctors simply didnt feel like curing :)",
f"",
f"{target.mention} You know there's no vaccine for stupidity right?",
f"",
f"",
f"",
f"",
]
#/warn @Call Me♥#5566 Pissing me off when I'm pissed off with people not posting in #general-media
await ctx.send(random.choice(responses))
@commands.command(aliases=['comp', 'Compliment', 'Comp'])
@commands.has_any_role('Hamothy', "izzy")
async def compliment(self, ctx, target: discord.Member):
responses = [
f"{target.mention} is the most adorable uwu :heart_eyes: :heart_eyes: ",
f"{target.mention} You have my ENTIRE HEART UvU",
f"{target.mention} Hun you're CUTE UwU :pleading_face: :flushed: :pleading_face: :flushed: :pleading_face:",
f"I love {target.mention} so so much :heartbeat: :heartbeat: :heartbeat: ",
f"My heart is full of love for you {target.mention}",
f"{target.mention} I admire your greatness so much that I consider making a fan club to become your #1 fan (´꒳`)",
f"{target.mention} has no flaws, only special effects :))",
f"{target.mention}'s smile is brighter than sunlight, so smile more often ( ◠‿◠ )",
f"",
f"",
]
# await ctx.send(random.choice(responses))
await ctx.send(random.choice(responses))
# @client.command(aliases=["Hug"])
# @commands.has_any_role('Hamothy')
# async def hug(self, ctx):
# await self.bot.say("hugs {}".format(ctx.message.author.mention()))
# Bot ~8Ball command
@commands.command(aliases=['8ball', '8Ball'])
@cooldown(1, 5, BucketType.channel)
async def _8ball(self, ctx, *, question):
channels = ["bot-commands"]
if str(ctx.channel) not in channels:
message = await ctx.send("Sorry! I only work in #bot-commands!")
message = await ctx.send(error_function())
# Let the user read the message for 2.5 seconds
await asyncio.sleep(2.5)
@ -67,7 +90,6 @@ class Fun(commands.Cog):
"Idk idiot lmao",
"Why are you even asking me",
"It's not like I can read your question",
"Shut the fuck up NOW",
"Zara wants to protest your question",
"Stitch will definitely get back to you",
"*Kakashi slams you to the wall*",
@ -83,16 +105,14 @@ class Fun(commands.Cog):
"Find something better to do with your spare time smh",
"Sure but did you know that Izzy smells?",
"No but did you know that Stitch smells?",
"Get your dick back in your pants smh",
"Get the fuck back to horny jail RIGHT NOW",
"Get back to horny jail RIGHT NOW",
"Nick Cock Bro",
"Nice Tits",
"Dm Cloud for the answer",
"No",
"Yes",
"Pffft you wish",
"Never in a million years",
"Pathetic. You're wasting your time",
"You're wasting your time asking me",
"Taz is too busy simping over Anonymous to care",
"Leave me alone. I'm sad :(",
"Shoot your Shot King",
@ -111,13 +131,24 @@ class Fun(commands.Cog):
"Marshall would love to agree with you",
"That's so litty titty bro",
"I'm Izzy and I approve of this message",
"Naughty naughty girl",
"Inna would love to agree with you",
"Hamothy has used his godlike like powers to align the stars for you, it must be true",
"Gabriel appears out of thin air and smites you",
"Yes yes yes!!!",
"",
"",
"",
"",
"",
"",
]
await ctx.send(f'Question: {question}\nAnswer: {random.choice(responses)}')
def error_function():
return "Sorry! I only work in #bot-commands!"
def setup(bot):
bot.add_cog(Fun(bot))

@ -13,151 +13,29 @@ class Waifus(commands.Cog):
@commands.command(aliases=['Kakashi'])
@cooldown(1, 0, BucketType.channel)
async def kakashi(self, ctx):
channels = ["bot-commands"]
if str(ctx.channel) not in channels:
message = await ctx.send("Sorry! I only work in #bot-commands!")
message = await ctx.send(error_function())
# Let the user read the message for 2.5 seconds
await asyncio.sleep(2.5)
# Delete the message
await message.delete()
if str(ctx.channel) in channels:
kakashi1 = "https://cdn.discordapp.com/attachments/714671068941647933/717201077346238514/image0.jpg"
kakashi2 = "https://cdn.discordapp.com/attachments/714671068941647933/717201077669331036/image1.jpg"
kakashi3 = "https://cdn.discordapp.com/attachments/714671068941647933/717201077941829722/image2.jpg"
kakashi4 = "https://cdn.discordapp.com/attachments/714671068941647933/717201078633889913/image4.jpg"
kakashi5 = "https://cdn.discordapp.com/attachments/714671068941647933/717201078885810176/image5.jpg"
kakashi6 = "https://cdn.discordapp.com/attachments/714671068941647933/717203540048871456/40964a8ec3616dd143db1ac63c4090ee.jpg"
kakashi7 = "https://media.discordapp.net/attachments/714671068941647933/717203546772340846/4707601f950c412dd6978c8264308632.jpg"
kakashi8 = "https://media.discordapp.net/attachments/714671068941647933/717203597774946354/7941b52067df70825ae3a9051acfd98d.jpg"
kakashi9 = "https://media.discordapp.net/attachments/714671068941647933/717203650333900840/dafb0bc78adc3548e9c9b24460d7c10d.jpg"
kakashi10 = "https://media.discordapp.net/attachments/714671068941647933/717203693925040188/aad4edeac8e034683b5602cf01a41333.jpg?width=465&height=658"
kakashi11 = "https://media.discordapp.net/attachments/714671068941647933/717203717085986836/5851485577679be2a09bdebef7e35522.jpg?width=390&height=658"
kakashi12 = "https://media.discordapp.net/attachments/714671068941647933/717203783016513626/e2a746123c1e36d995fa95c44a3c3f85.jpg"
kakashi13 = "https://media.discordapp.net/attachments/714671068941647933/717203811923394611/268a3266d4c255b72925a3eb541f4cf5.jpg?width=517&height=657"
kakashi14 = "https://media.discordapp.net/attachments/714671068941647933/717203866986479636/b283f71be006957107926e1d5d9ab60e.jpg?width=591&height=658"
kakashi15 = "https://cdn.discordapp.com/attachments/714671068941647933/717203972925947984/6f46bb96761b673f1c4f4b5584bf1ba8.jpg"
kakashi16 = "https://cdn.discordapp.com/attachments/714671068941647933/717204020711915581/4025c1241a206406555bd6ab53640291.jpg"
kakashi17 = "https://cdn.discordapp.com/attachments/714671068941647933/717204198491422770/94287174f2f5e5316144981190a38c66.jpg"
kakashi18 = "https://cdn.discordapp.com/attachments/714671068941647933/717204289755283547/a9868fb38857dd51ccc93a3e202644ff.gif"
kakashi19 = "https://cdn.discordapp.com/attachments/714671068941647933/717204351638175784/3967dabc9b069080daded9a38f1d9e49.jpg"
kakashi20 = "https://cdn.discordapp.com/attachments/714671068941647933/717204405178597396/3d063a07af0cfa320a100e169c959ff4.jpg"
kakashi21 = "https://cdn.discordapp.com/attachments/714671068941647933/717204454264537151/4c607bbcc9a360257e1d14b5c9858b21.jpg"
kakashi22 = "https://cdn.discordapp.com/attachments/714671068941647933/717204495939141692/9d85777e4a452f2f38464f8a11dece5b.jpg"
kakashi23 = "https://cdn.discordapp.com/attachments/714671068941647933/717204530760122478/edeaa333ed2fb68aa1205a783d0bb783.jpg"
kakashi24 = "https://cdn.discordapp.com/attachments/714671068941647933/717204561936252958/4f39f6de439a99b4113f6a33fd803079.jpg"
kakashi25 = "https://cdn.discordapp.com/attachments/714671068941647933/717204627484967012/ebb8b6713aff32745503d6cbe8996569.jpg"
kakashi26 = "https://cdn.discordapp.com/attachments/714671068941647933/717204713648685126/a6cb9a07745c163d14d736e077765ec8.gif"
kakashi27 = "https://cdn.discordapp.com/attachments/714671068941647933/717204734905417738/3a081283ef670fd5326a694b7d41d35d.jpg"
kakashi28 = "https://cdn.discordapp.com/attachments/714671068941647933/717204879155921006/864704a29ef1201f78f7f8fd71f57cf7.gif"
kakashi29 = "https://cdn.discordapp.com/attachments/714671068941647933/717204999792361472/d9b273a711ccf1e6af531443a4cf06b5.jpg"
kakashi30 = "https://cdn.discordapp.com/attachments/714671068941647933/717205121259405332/d2426eff482c18af2586e1fd2499d3d5.jpg"
kakashi31 = "https://cdn.discordapp.com/attachments/714671068941647933/717205186463924224/7e27f5a97a80444ab5fc773e4d09d1bb.jpg"
kakashi32 = "https://cdn.discordapp.com/attachments/714671068941647933/717205371835514930/IMG_20191212_215715_438.jpg"
kakashi33 = "https://cdn.discordapp.com/attachments/714671068941647933/717205515519655976/df09731e2b38c1f50cc57f4600d937f5.jpg"
kakashi34 = "https://cdn.discordapp.com/attachments/714671068941647933/717206154882842695/image0.jpg"
kakashi35 = "https://cdn.discordapp.com/attachments/714671068941647933/717206155356798986/image1.jpg"
kakashi36 = "https://cdn.discordapp.com/attachments/714671068941647933/717206155562057780/image2.jpg"
kakashi37 = "https://cdn.discordapp.com/attachments/714671068941647933/717206155797200896/image3.jpg"
kakashi38 = "https://cdn.discordapp.com/attachments/714671068941647933/717206156031819786/image4.jpg"
kakashi39 = "https://cdn.discordapp.com/attachments/714671068941647933/717206156191334460/image5.jpg"
kakashi40 = "https://cdn.discordapp.com/attachments/714671068941647933/717206156673679380/image6.gif"
kakashi41 = "https://cdn.discordapp.com/attachments/714671068941647933/717206157227327578/image7.jpg"
kakashi42 = "https://cdn.discordapp.com/attachments/714671068941647933/717206621121544230/image0.jpg"
kakashi43 = "https://cdn.discordapp.com/attachments/714671068941647933/717206621310418954/image1.jpg"
kakashi44 = "https://cdn.discordapp.com/attachments/714671068941647933/717206621666672721/image2.jpg"
kakashi45 = "https://cdn.discordapp.com/attachments/714671068941647933/717206621993959474/image3.jpg"
kakashi46 = "https://cdn.discordapp.com/attachments/714671068941647933/717206622249943050/image4.jpg"
kakashi47 = "https://cdn.discordapp.com/attachments/714671068941647933/717206622489018458/image5.jpg"
kakashi48 = "https://cdn.discordapp.com/attachments/714671068941647933/717206622979489792/image6.jpg"
kakashi49 = "https://cdn.discordapp.com/attachments/714671068941647933/717545579713921065/image0.gif"
kakashi50 = "https://cdn.discordapp.com/attachments/714671068941647933/717545580070699068/image1.gif"
kakashi51 = "https://cdn.discordapp.com/attachments/714671068941647933/717545580393398332/image2.gif"
kakashi52 = "https://cdn.discordapp.com/attachments/714671068941647933/717545580804702228/image3.gif"
kakashi53 = "https://cdn.discordapp.com/attachments/714671068941647933/717545581299499179/image4.jpg"
kakashi54 = "https://cdn.discordapp.com/attachments/714671068941647933/717545581526122586/image5.jpg"
kakashi55 = "https://cdn.discordapp.com/attachments/714671068941647933/717545581815529532/image6.jpg"
kakashi56 = "https://cdn.discordapp.com/attachments/714671068941647933/717545582046085140/image7.jpg"
kakashi57 = "https://cdn.discordapp.com/attachments/714671068941647933/717545582234697748/image8.jpg"
kakashi58 = "https://cdn.discordapp.com/attachments/714671068941647933/717545582427766784/image9.jpg"
kakashi59 = "https://cdn.discordapp.com/attachments/714671068941647933/717547623334019102/image0.gif"
kakashi60 = "https://cdn.discordapp.com/attachments/714671068941647933/717547623762100254/image1.jpg"
kakashi61 = "https://cdn.discordapp.com/attachments/714671068941647933/717547624122810388/image2.jpg"
kakashi62 = "https://cdn.discordapp.com/attachments/714671068941647933/717547624374206554/image3.jpg"
kakashi63 = "https://cdn.discordapp.com/attachments/714671068941647933/717547624655355944/image4.jpg"
kakashi64 = "https://cdn.discordapp.com/attachments/714671068941647933/717547624906883082/image5.jpg"
kakashi65 = "https://cdn.discordapp.com/attachments/714671068941647933/717547625095626752/image6.jpg"
kakashi66 = "https://cdn.discordapp.com/attachments/714671068941647933/717547625557262417/image7.jpg"
kakashi67 = "https://cdn.discordapp.com/attachments/714671068941647933/717547625762521167/image8.gif"
kakashi68 = "https://cdn.discordapp.com/attachments/714671068941647933/717547626081288242/image9.jpg"
kakashi69 = "https://cdn.discordapp.com/attachments/714671068941647933/717548032249430016/image0.jpg"
kakashi70 = "https://cdn.discordapp.com/attachments/714671068941647933/717548032614465556/image1.jpg"
kakashi71 = "https://cdn.discordapp.com/attachments/714671068941647933/717548033000079380/image2.jpg"
kakashi72 = "https://cdn.discordapp.com/attachments/714671068941647933/717548033344143410/image3.jpg"
kakashi73 = "https://cdn.discordapp.com/attachments/714671068941647933/717548033612709999/image4.jpg"
kakashi74 = "https://cdn.discordapp.com/attachments/714671068941647933/717548033868300298/image5.jpg"
kakashi75 = "https://cdn.discordapp.com/attachments/714671068941647933/717548034149449738/image6.jpg"
kakashi76 = "https://cdn.discordapp.com/attachments/714671068941647933/717548034359296046/image7.jpg"
kakashi77 = "https://cdn.discordapp.com/attachments/714671068941647933/717548034631663616/image8.jpg"
kakashi78 = "https://cdn.discordapp.com/attachments/714671068941647933/717548034820538406/image9.jpg"
kakashi79 = "https://cdn.discordapp.com/attachments/714671068941647933/717551546946158602/image0.jpg"
kakashi80 = "https://cdn.discordapp.com/attachments/714671068941647933/717551547197947954/image1.jpg"
kakashi81 = "https://cdn.discordapp.com/attachments/714671068941647933/717551547525103616/image2.gif"
kakashi82 = "https://cdn.discordapp.com/attachments/714671068941647933/717551547776630824/image3.jpg"
kakashi83 = "https://cdn.discordapp.com/attachments/714671068941647933/717551548170764398/image4.jpg"
kakashi84 = "https://cdn.discordapp.com/attachments/714671068941647933/717551548380610570/image5.jpg"
kakashi85 = "https://cdn.discordapp.com/attachments/714671068941647933/717551548720349235/image6.jpg"
kakashi86 = "https://cdn.discordapp.com/attachments/714671068941647933/717551549139648592/image7.jpg"
kakashi87 = "https://cdn.discordapp.com/attachments/714671068941647933/717551549357883512/image8.jpg"
kakashi88 = "https://cdn.discordapp.com/attachments/714671068941647933/717551549525786745/image9.jpg"
kakashi89 = "https://cdn.discordapp.com/attachments/714671068941647933/717551728316121148/image0.jpg"
kakashi90 = "https://cdn.discordapp.com/attachments/714671068941647933/717551728873963610/image1.jpg"
kakashi91 = "https://cdn.discordapp.com/attachments/714671068941647933/717551729343725568/image2.jpg"
kakashi92 = "https://cdn.discordapp.com/attachments/714671068941647933/717551729343725568/image2.jpg"
kakashi93 = "https://cdn.discordapp.com/attachments/714671068941647933/717551729683595334/image3.jpg"
kakashi94 = "https://cdn.discordapp.com/attachments/714671068941647933/717551730065276948/image4.jpg"
kakashi95 = "https://cdn.discordapp.com/attachments/714671068941647933/717551730400821298/image5.jpg"
kakashi96 = "https://cdn.discordapp.com/attachments/714671068941647933/717551731537477662/image6.jpg"
kakashi97 = "https://cdn.discordapp.com/attachments/714671068941647933/717551731969622039/image7.jpg"
kakashi98 = "https://cdn.discordapp.com/attachments/714671068941647933/717551732338458654/image8.jpg"
kakashi99 = "https://cdn.discordapp.com/attachments/714671068941647933/717551732594442290/image9.jpg"
kakashi100 = "https://cdn.discordapp.com/attachments/714671068941647933/717552058877739119/image0.gif"
kakashi_array = [kakashi1, kakashi2, kakashi3, kakashi4, kakashi5, kakashi6, kakashi7, kakashi8, kakashi9,
kakashi10,
kakashi11, kakashi12, kakashi13, kakashi14, kakashi15, kakashi16, kakashi17, kakashi18,
kakashi19,
kakashi20,
kakashi21, kakashi22, kakashi23, kakashi24, kakashi25, kakashi26, kakashi27, kakashi28,
kakashi29,
kakashi30,
kakashi31, kakashi32, kakashi33, kakashi34, kakashi35, kakashi36, kakashi37, kakashi38,
kakashi39,
kakashi40,
kakashi41, kakashi42, kakashi43, kakashi44, kakashi45, kakashi46, kakashi47, kakashi48,
kakashi49,
kakashi50,
kakashi51, kakashi52, kakashi53, kakashi54, kakashi55, kakashi56, kakashi57, kakashi58,
kakashi59,
kakashi60,
kakashi61, kakashi62, kakashi63, kakashi64, kakashi65, kakashi66, kakashi67, kakashi68,
kakashi69,
kakashi70,
kakashi71, kakashi72, kakashi73, kakashi74, kakashi75, kakashi76, kakashi77, kakashi78,
kakashi79,
kakashi80,
kakashi81, kakashi82, kakashi83, kakashi84, kakashi85, kakashi86, kakashi87, kakashi88,
kakashi89,
kakashi90,
kakashi91, kakashi92, kakashi93, kakashi94, kakashi95, kakashi96, kakashi97, kakashi98,
kakashi99,
kakashi100]
with open('kakashiImages.txt') as file:
kakashi_array = file.readlines()
if str(ctx.channel) in channels:
embed = discord.Embed(title="```Random Kakashi Image```", colour=discord.Colour(0xff0000), )
embed.set_image(url=random.choice(kakashi_array))
await ctx.send(embed=embed)
def error_function():
return "Sorry! I only work in #bot-commands!"
def setup(bot):
bot.add_cog(Waifus(bot))

@ -0,0 +1,100 @@
https://cdn.discordapp.com/attachments/714671068941647933/717201077346238514/image0.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717201077669331036/image1.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717201077941829722/image2.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717201078633889913/image4.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717201078885810176/image5.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717203540048871456/40964a8ec3616dd143db1ac63c4090ee.jpg
https://media.discordapp.net/attachments/714671068941647933/717203546772340846/4707601f950c412dd6978c8264308632.jpg
https://media.discordapp.net/attachments/714671068941647933/717203597774946354/7941b52067df70825ae3a9051acfd98d.jpg
https://media.discordapp.net/attachments/714671068941647933/717203650333900840/dafb0bc78adc3548e9c9b24460d7c10d.jpg
https://media.discordapp.net/attachments/714671068941647933/717203693925040188/aad4edeac8e034683b5602cf01a41333.jpg?width=465&height=658
https://media.discordapp.net/attachments/714671068941647933/717203717085986836/5851485577679be2a09bdebef7e35522.jpg?width=390&height=658
https://media.discordapp.net/attachments/714671068941647933/717203783016513626/e2a746123c1e36d995fa95c44a3c3f85.jpg
https://media.discordapp.net/attachments/714671068941647933/717203811923394611/268a3266d4c255b72925a3eb541f4cf5.jpg?width=517&height=657
https://media.discordapp.net/attachments/714671068941647933/717203866986479636/b283f71be006957107926e1d5d9ab60e.jpg?width=591&height=658
https://cdn.discordapp.com/attachments/714671068941647933/717203972925947984/6f46bb96761b673f1c4f4b5584bf1ba8.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717204020711915581/4025c1241a206406555bd6ab53640291.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717204198491422770/94287174f2f5e5316144981190a38c66.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717204289755283547/a9868fb38857dd51ccc93a3e202644ff.gif
https://cdn.discordapp.com/attachments/714671068941647933/717204351638175784/3967dabc9b069080daded9a38f1d9e49.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717204405178597396/3d063a07af0cfa320a100e169c959ff4.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717204454264537151/4c607bbcc9a360257e1d14b5c9858b21.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717204495939141692/9d85777e4a452f2f38464f8a11dece5b.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717204530760122478/edeaa333ed2fb68aa1205a783d0bb783.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717204561936252958/4f39f6de439a99b4113f6a33fd803079.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717204627484967012/ebb8b6713aff32745503d6cbe8996569.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717204713648685126/a6cb9a07745c163d14d736e077765ec8.gif
https://cdn.discordapp.com/attachments/714671068941647933/717204734905417738/3a081283ef670fd5326a694b7d41d35d.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717204879155921006/864704a29ef1201f78f7f8fd71f57cf7.gif
https://cdn.discordapp.com/attachments/714671068941647933/717204999792361472/d9b273a711ccf1e6af531443a4cf06b5.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717205121259405332/d2426eff482c18af2586e1fd2499d3d5.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717205186463924224/7e27f5a97a80444ab5fc773e4d09d1bb.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717205371835514930/IMG_20191212_215715_438.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717205515519655976/df09731e2b38c1f50cc57f4600d937f5.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717206154882842695/image0.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717206155356798986/image1.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717206155562057780/image2.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717206155797200896/image3.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717206156031819786/image4.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717206156191334460/image5.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717206156673679380/image6.gif
https://cdn.discordapp.com/attachments/714671068941647933/717206157227327578/image7.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717206621121544230/image0.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717206621310418954/image1.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717206621666672721/image2.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717206621993959474/image3.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717206622249943050/image4.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717206622489018458/image5.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717206622979489792/image6.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717545579713921065/image0.gif
https://cdn.discordapp.com/attachments/714671068941647933/717545580070699068/image1.gif
https://cdn.discordapp.com/attachments/714671068941647933/717545580393398332/image2.gif
https://cdn.discordapp.com/attachments/714671068941647933/717545580804702228/image3.gif
https://cdn.discordapp.com/attachments/714671068941647933/717545581299499179/image4.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717545581526122586/image5.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717545581815529532/image6.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717545582046085140/image7.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717545582234697748/image8.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717545582427766784/image9.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717547623334019102/image0.gif
https://cdn.discordapp.com/attachments/714671068941647933/717547623762100254/image1.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717547624122810388/image2.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717547624374206554/image3.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717547624655355944/image4.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717547624906883082/image5.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717547625095626752/image6.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717547625557262417/image7.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717547625762521167/image8.gif
https://cdn.discordapp.com/attachments/714671068941647933/717547626081288242/image9.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717548032249430016/image0.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717548032614465556/image1.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717548033000079380/image2.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717548033344143410/image3.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717548033612709999/image4.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717548033868300298/image5.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717548034149449738/image6.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717548034359296046/image7.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717548034631663616/image8.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717548034820538406/image9.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551546946158602/image0.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551547197947954/image1.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551547525103616/image2.gif
https://cdn.discordapp.com/attachments/714671068941647933/717551547776630824/image3.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551548170764398/image4.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551548380610570/image5.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551548720349235/image6.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551549139648592/image7.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551549357883512/image8.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551549525786745/image9.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551728316121148/image0.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551728873963610/image1.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551729343725568/image2.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551729343725568/image2.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551729683595334/image3.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551730065276948/image4.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551730400821298/image5.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551731537477662/image6.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551731969622039/image7.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551732338458654/image8.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717551732594442290/image9.jpg
https://cdn.discordapp.com/attachments/714671068941647933/717552058877739119/image0.gif

@ -0,0 +1,157 @@
/* vim:set noet ts=8 sw=8 : */
/* Greenlet object interface */
#ifndef Py_GREENLETOBJECT_H
#define Py_GREENLETOBJECT_H
#include <Python.h>
#ifdef __cplusplus
extern "C" {
#endif
#define GREENLET_VERSION "0.4.15"
#if PY_VERSION_HEX >= 0x030700A3
# define GREENLET_USE_EXC_INFO
#endif
typedef struct _greenlet {
PyObject_HEAD
char* stack_start;
char* stack_stop;
char* stack_copy;
intptr_t stack_saved;
struct _greenlet* stack_prev;
struct _greenlet* parent;
PyObject* run_info;
struct _frame* top_frame;
int recursion_depth;
PyObject* weakreflist;
#ifdef GREENLET_USE_EXC_INFO
_PyErr_StackItem* exc_info;
_PyErr_StackItem exc_state;
#else
PyObject* exc_type;
PyObject* exc_value;
PyObject* exc_traceback;
#endif
PyObject* dict;
} PyGreenlet;
#define PyGreenlet_Check(op) PyObject_TypeCheck(op, &PyGreenlet_Type)
#define PyGreenlet_MAIN(op) (((PyGreenlet*)(op))->stack_stop == (char*) -1)
#define PyGreenlet_STARTED(op) (((PyGreenlet*)(op))->stack_stop != NULL)
#define PyGreenlet_ACTIVE(op) (((PyGreenlet*)(op))->stack_start != NULL)
#define PyGreenlet_GET_PARENT(op) (((PyGreenlet*)(op))->parent)
#if (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 7) || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 1) || PY_MAJOR_VERSION > 3
#define GREENLET_USE_PYCAPSULE
#endif
/* C API functions */
/* Total number of symbols that are exported */
#define PyGreenlet_API_pointers 8
#define PyGreenlet_Type_NUM 0
#define PyExc_GreenletError_NUM 1
#define PyExc_GreenletExit_NUM 2
#define PyGreenlet_New_NUM 3
#define PyGreenlet_GetCurrent_NUM 4
#define PyGreenlet_Throw_NUM 5
#define PyGreenlet_Switch_NUM 6
#define PyGreenlet_SetParent_NUM 7
#ifndef GREENLET_MODULE
/* This section is used by modules that uses the greenlet C API */
static void **_PyGreenlet_API = NULL;
#define PyGreenlet_Type (*(PyTypeObject *) _PyGreenlet_API[PyGreenlet_Type_NUM])
#define PyExc_GreenletError \
((PyObject *) _PyGreenlet_API[PyExc_GreenletError_NUM])
#define PyExc_GreenletExit \
((PyObject *) _PyGreenlet_API[PyExc_GreenletExit_NUM])
/*
* PyGreenlet_New(PyObject *args)
*
* greenlet.greenlet(run, parent=None)
*/
#define PyGreenlet_New \
(* (PyGreenlet * (*)(PyObject *run, PyGreenlet *parent)) \
_PyGreenlet_API[PyGreenlet_New_NUM])
/*
* PyGreenlet_GetCurrent(void)
*
* greenlet.getcurrent()
*/
#define PyGreenlet_GetCurrent \
(* (PyGreenlet * (*)(void)) _PyGreenlet_API[PyGreenlet_GetCurrent_NUM])
/*
* PyGreenlet_Throw(
* PyGreenlet *greenlet,
* PyObject *typ,
* PyObject *val,
* PyObject *tb)
*
* g.throw(...)
*/
#define PyGreenlet_Throw \
(* (PyObject * (*) \
(PyGreenlet *self, PyObject *typ, PyObject *val, PyObject *tb)) \
_PyGreenlet_API[PyGreenlet_Throw_NUM])
/*
* PyGreenlet_Switch(PyGreenlet *greenlet, PyObject *args)
*
* g.switch(*args, **kwargs)
*/
#define PyGreenlet_Switch \
(* (PyObject * (*)(PyGreenlet *greenlet, PyObject *args, PyObject *kwargs)) \
_PyGreenlet_API[PyGreenlet_Switch_NUM])
/*
* PyGreenlet_SetParent(PyObject *greenlet, PyObject *new_parent)
*
* g.parent = new_parent
*/
#define PyGreenlet_SetParent \
(* (int (*)(PyGreenlet *greenlet, PyGreenlet *nparent)) \
_PyGreenlet_API[PyGreenlet_SetParent_NUM])
/* Macro that imports greenlet and initializes C API */
#ifdef GREENLET_USE_PYCAPSULE
#define PyGreenlet_Import() \
{ \
_PyGreenlet_API = (void**)PyCapsule_Import("greenlet._C_API", 0); \
}
#else
#define PyGreenlet_Import() \
{ \
PyObject *module = PyImport_ImportModule("greenlet"); \
if (module != NULL) { \
PyObject *c_api_object = PyObject_GetAttrString( \
module, "_C_API"); \
if (c_api_object != NULL && PyCObject_Check(c_api_object)) { \
_PyGreenlet_API = \
(void **) PyCObject_AsVoidPtr(c_api_object); \
Py_DECREF(c_api_object); \
} \
Py_DECREF(module); \
} \
}
#endif
#endif /* GREENLET_MODULE */
#ifdef __cplusplus
}
#endif
#endif /* !Py_GREENLETOBJECT_H */

@ -0,0 +1,194 @@
Metadata-Version: 2.1
Name: dill
Version: 0.3.1.1
Summary: serialize all of python
Home-page: https://pypi.org/project/dill
Author: Mike McKerns
Maintainer: Mike McKerns
License: 3-clause BSD
Download-URL: https://github.com/uqfoundation/dill/releases/download/dill-0.3.1.1/dill-0.3.1.1.tar.gz
Description: -----------------------------
dill: serialize all of python
-----------------------------
About Dill
==========
``dill`` extends python's ``pickle`` module for serializing and de-serializing
python objects to the majority of the built-in python types. Serialization
is the process of converting an object to a byte stream, and the inverse
of which is converting a byte stream back to on python object hierarchy.
``dill`` provides the user the same interface as the ``pickle`` module, and
also includes some additional features. In addition to pickling python
objects, ``dill`` provides the ability to save the state of an interpreter
session in a single command. Hence, it would be feasable to save a
interpreter session, close the interpreter, ship the pickled file to
another computer, open a new interpreter, unpickle the session and
thus continue from the 'saved' state of the original interpreter
session.
``dill`` can be used to store python objects to a file, but the primary
usage is to send python objects across the network as a byte stream.
``dill`` is quite flexible, and allows arbitrary user defined classes
and functions to be serialized. Thus ``dill`` is not intended to be
secure against erroneously or maliciously constructed data. It is
left to the user to decide whether the data they unpickle is from
a trustworthy source.
``dill`` is part of ``pathos``, a python framework for heterogeneous computing.
``dill`` is in active development, so any user feedback, bug reports, comments,
or suggestions are highly appreciated. A list of known issues is maintained
at http://trac.mystic.cacr.caltech.edu/project/pathos/query.html, with a public
ticket list at https://github.com/uqfoundation/dill/issues.
Major Features
==============
``dill`` can pickle the following standard types:
- none, type, bool, int, long, float, complex, str, unicode,
- tuple, list, dict, file, buffer, builtin,
- both old and new style classes,
- instances of old and new style classes,
- set, frozenset, array, functions, exceptions
``dill`` can also pickle more 'exotic' standard types:
- functions with yields, nested functions, lambdas,
- cell, method, unboundmethod, module, code, methodwrapper,
- dictproxy, methoddescriptor, getsetdescriptor, memberdescriptor,
- wrapperdescriptor, xrange, slice,
- notimplemented, ellipsis, quit
``dill`` cannot yet pickle these standard types:
- frame, generator, traceback
``dill`` also provides the capability to:
- save and load python interpreter sessions
- save and extract the source code from functions and classes
- interactively diagnose pickling errors
Current Release
===============
This documentation is for version ``dill-0.3.1.1``.
The latest released version of ``dill`` is available from:
https://pypi.org/project/dill
``dill`` is distributed under a 3-clause BSD license.
>>> import dill
>>> print (dill.license())
Development Version
===================
You can get the latest development version with all the shiny new features at:
https://github.com/uqfoundation
If you have a new contribution, please submit a pull request.
Installation
============
``dill`` is packaged to install from source, so you must
download the tarball, unzip, and run the installer::
[download]
$ tar -xvzf dill-0.3.1.1.tar.gz
$ cd dill-0.3.1.1
$ python setup py build
$ python setup py install
You will be warned of any missing dependencies and/or settings
after you run the "build" step above.
Alternately, ``dill`` can be installed with ``pip`` or ``easy_install``::
$ pip install dill
Requirements
============
``dill`` requires:
- ``python``, **version >= 2.6** or **version >= 3.1**, or ``pypy``
Optional requirements:
- ``setuptools``, **version >= 0.6**
- ``pyreadline``, **version >= 1.7.1** (on windows)
- ``objgraph``, **version >= 1.7.2**
More Information
================
Probably the best way to get started is to look at the documentation at
http://dill.rtfd.io. Also see ``dill.tests`` for a set of scripts that
demonstrate how ``dill`` can serialize different python objects. You can
run the test suite with ``python -m dill.tests``. The contents of any
pickle file can be examined with ``undill``. As ``dill`` conforms to
the ``pickle`` interface, the examples and documentation found at
http://docs.python.org/library/pickle.html also apply to ``dill``
if one will ``import dill as pickle``. The source code is also generally
well documented, so further questions may be resolved by inspecting the
code itself. Please feel free to submit a ticket on github, or ask a
question on stackoverflow (**@Mike McKerns**).
If you would like to share how you use ``dill`` in your work, please send
an email (to **mmckerns at uqfoundation dot org**).
Citation
========
If you use ``dill`` to do research that leads to publication, we ask that you
acknowledge use of ``dill`` by citing the following in your publication::
M.M. McKerns, L. Strand, T. Sullivan, A. Fang, M.A.G. Aivazis,
"Building a framework for predictive science", Proceedings of
the 10th Python in Science Conference, 2011;
http://arxiv.org/pdf/1202.1056
Michael McKerns and Michael Aivazis,
"pathos: a framework for heterogeneous computing", 2010- ;
http://trac.mystic.cacr.caltech.edu/project/pathos
Please see http://trac.mystic.cacr.caltech.edu/project/pathos or
http://arxiv.org/pdf/1202.1056 for further information.
Platform: Linux
Platform: Windows
Platform: Mac
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.1
Classifier: Programming Language :: Python :: 3.2
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Software Development
Requires-Python: >=2.6, !=3.0.*
Provides-Extra: readline
Provides-Extra: graph

@ -0,0 +1,47 @@
LICENSE
MANIFEST.in
README
setup.cfg
setup.py
tox.ini
dill/__diff.py
dill/__init__.py
dill/_dill.py
dill/_objects.py
dill/detect.py
dill/info.py
dill/objtypes.py
dill/pointers.py
dill/settings.py
dill/source.py
dill/temp.py
dill.egg-info/PKG-INFO
dill.egg-info/SOURCES.txt
dill.egg-info/dependency_links.txt
dill.egg-info/not-zip-safe
dill.egg-info/requires.txt
dill.egg-info/top_level.txt
scripts/get_objgraph
scripts/undill
tests/__init__.py
tests/__main__.py
tests/test_check.py
tests/test_classdef.py
tests/test_detect.py
tests/test_diff.py
tests/test_extendpickle.py
tests/test_file.py
tests/test_functions.py
tests/test_functors.py
tests/test_mixins.py
tests/test_module.py
tests/test_moduledict.py
tests/test_nested.py
tests/test_objects.py
tests/test_properties.py
tests/test_recursive.py
tests/test_restricted.py
tests/test_selected.py
tests/test_source.py
tests/test_temp.py
tests/test_weakref.py

@ -0,0 +1,74 @@
..\..\..\Scripts\get_objgraph
..\..\..\Scripts\undill
..\dill\__diff.py
..\dill\__init__.py
..\dill\__pycache__\__diff.cpython-36.pyc
..\dill\__pycache__\__init__.cpython-36.pyc
..\dill\__pycache__\_dill.cpython-36.pyc
..\dill\__pycache__\_objects.cpython-36.pyc
..\dill\__pycache__\detect.cpython-36.pyc
..\dill\__pycache__\info.cpython-36.pyc
..\dill\__pycache__\objtypes.cpython-36.pyc
..\dill\__pycache__\pointers.cpython-36.pyc
..\dill\__pycache__\settings.cpython-36.pyc
..\dill\__pycache__\source.cpython-36.pyc
..\dill\__pycache__\temp.cpython-36.pyc
..\dill\_dill.py
..\dill\_objects.py
..\dill\detect.py
..\dill\info.py
..\dill\objtypes.py
..\dill\pointers.py
..\dill\settings.py
..\dill\source.py
..\dill\temp.py
..\dill\tests\__init__.py
..\dill\tests\__main__.py
..\dill\tests\__pycache__\__init__.cpython-36.pyc
..\dill\tests\__pycache__\__main__.cpython-36.pyc
..\dill\tests\__pycache__\test_check.cpython-36.pyc
..\dill\tests\__pycache__\test_classdef.cpython-36.pyc
..\dill\tests\__pycache__\test_detect.cpython-36.pyc
..\dill\tests\__pycache__\test_diff.cpython-36.pyc
..\dill\tests\__pycache__\test_extendpickle.cpython-36.pyc
..\dill\tests\__pycache__\test_file.cpython-36.pyc
..\dill\tests\__pycache__\test_functions.cpython-36.pyc
..\dill\tests\__pycache__\test_functors.cpython-36.pyc
..\dill\tests\__pycache__\test_mixins.cpython-36.pyc
..\dill\tests\__pycache__\test_module.cpython-36.pyc
..\dill\tests\__pycache__\test_moduledict.cpython-36.pyc
..\dill\tests\__pycache__\test_nested.cpython-36.pyc
..\dill\tests\__pycache__\test_objects.cpython-36.pyc
..\dill\tests\__pycache__\test_properties.cpython-36.pyc
..\dill\tests\__pycache__\test_recursive.cpython-36.pyc
..\dill\tests\__pycache__\test_restricted.cpython-36.pyc
..\dill\tests\__pycache__\test_selected.cpython-36.pyc
..\dill\tests\__pycache__\test_source.cpython-36.pyc
..\dill\tests\__pycache__\test_temp.cpython-36.pyc
..\dill\tests\__pycache__\test_weakref.cpython-36.pyc
..\dill\tests\test_check.py
..\dill\tests\test_classdef.py
..\dill\tests\test_detect.py
..\dill\tests\test_diff.py
..\dill\tests\test_extendpickle.py
..\dill\tests\test_file.py
..\dill\tests\test_functions.py
..\dill\tests\test_functors.py
..\dill\tests\test_mixins.py
..\dill\tests\test_module.py
..\dill\tests\test_moduledict.py
..\dill\tests\test_nested.py
..\dill\tests\test_objects.py
..\dill\tests\test_properties.py
..\dill\tests\test_recursive.py
..\dill\tests\test_restricted.py
..\dill\tests\test_selected.py
..\dill\tests\test_source.py
..\dill\tests\test_temp.py
..\dill\tests\test_weakref.py
PKG-INFO
SOURCES.txt
dependency_links.txt
not-zip-safe
requires.txt
top_level.txt

@ -0,0 +1,6 @@
[graph]
objgraph>=1.7.2
[readline]
pyreadline>=1.7.1

@ -0,0 +1,240 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
"""
Module to show if an object has changed since it was memorised
"""
import os
import sys
import types
try:
import numpy
HAS_NUMPY = True
except:
HAS_NUMPY = False
try:
import builtins
except ImportError:
import __builtin__ as builtins
# pypy doesn't use reference counting
getrefcount = getattr(sys, 'getrefcount', lambda x:0)
# memo of objects indexed by id to a tuple (attributes, sequence items)
# attributes is a dict indexed by attribute name to attribute id
# sequence items is either a list of ids, of a dictionary of keys to ids
memo = {}
id_to_obj = {}
# types that cannot have changing attributes
builtins_types = set((str, list, dict, set, frozenset, int))
dont_memo = set(id(i) for i in (memo, sys.modules, sys.path_importer_cache,
os.environ, id_to_obj))
def get_attrs(obj):
"""
Gets all the attributes of an object though its __dict__ or return None
"""
if type(obj) in builtins_types \
or type(obj) is type and obj in builtins_types:
return
try:
return obj.__dict__
except:
return
def get_seq(obj, cache={str: False, frozenset: False, list: True, set: True,
dict: True, tuple: True, type: False,
types.ModuleType: False, types.FunctionType: False,
types.BuiltinFunctionType: False}):
"""
Gets all the items in a sequence or return None
"""
try:
o_type = obj.__class__
except AttributeError:
o_type = type(obj)
hsattr = hasattr
if o_type in cache:
if cache[o_type]:
if hsattr(obj, "copy"):
return obj.copy()
return obj
elif HAS_NUMPY and o_type in (numpy.ndarray, numpy.ma.core.MaskedConstant):
if obj.shape and obj.size:
return obj
else:
return []
elif hsattr(obj, "__contains__") and hsattr(obj, "__iter__") \
and hsattr(obj, "__len__") and hsattr(o_type, "__contains__") \
and hsattr(o_type, "__iter__") and hsattr(o_type, "__len__"):
cache[o_type] = True
if hsattr(obj, "copy"):
return obj.copy()
return obj
else:
cache[o_type] = False
return None
def memorise(obj, force=False):
"""
Adds an object to the memo, and recursively adds all the objects
attributes, and if it is a container, its items. Use force=True to update
an object already in the memo. Updating is not recursively done.
"""
obj_id = id(obj)
if obj_id in memo and not force or obj_id in dont_memo:
return
id_ = id
g = get_attrs(obj)
if g is None:
attrs_id = None
else:
attrs_id = dict((key,id_(value)) for key, value in g.items())
s = get_seq(obj)
if s is None:
seq_id = None
elif hasattr(s, "items"):
seq_id = dict((id_(key),id_(value)) for key, value in s.items())
elif not hasattr(s, "__len__"): #XXX: avoid TypeError from unexpected case
seq_id = None
else:
seq_id = [id_(i) for i in s]
memo[obj_id] = attrs_id, seq_id
id_to_obj[obj_id] = obj
mem = memorise
if g is not None:
[mem(value) for key, value in g.items()]
if s is not None:
if hasattr(s, "items"):
[(mem(key), mem(item))
for key, item in s.items()]
else:
if hasattr(s, '__len__'):
[mem(item) for item in s]
else: mem(s)
def release_gone():
itop, mp, src = id_to_obj.pop, memo.pop, getrefcount
[(itop(id_), mp(id_)) for id_, obj in list(id_to_obj.items())
if src(obj) < 4] #XXX: correct for pypy?
def whats_changed(obj, seen=None, simple=False, first=True):
"""
Check an object against the memo. Returns a list in the form
(attribute changes, container changed). Attribute changes is a dict of
attribute name to attribute value. container changed is a boolean.
If simple is true, just returns a boolean. None for either item means
that it has not been checked yet
"""
# Special cases
if first:
# ignore the _ variable, which only appears in interactive sessions
if "_" in builtins.__dict__:
del builtins._
if seen is None:
seen = {}
obj_id = id(obj)
if obj_id in seen:
if simple:
return any(seen[obj_id])
return seen[obj_id]
# Safety checks
if obj_id in dont_memo:
seen[obj_id] = [{}, False]
if simple:
return False
return seen[obj_id]
elif obj_id not in memo:
if simple:
return True
else:
raise RuntimeError("Object not memorised " + str(obj))
seen[obj_id] = ({}, False)
chngd = whats_changed
id_ = id
# compare attributes
attrs = get_attrs(obj)
if attrs is None:
changed = {}
else:
obj_attrs = memo[obj_id][0]
obj_get = obj_attrs.get
changed = dict((key,None) for key in obj_attrs if key not in attrs)
for key, o in attrs.items():
if id_(o) != obj_get(key, None) or chngd(o, seen, True, False):
changed[key] = o
# compare sequence
items = get_seq(obj)
seq_diff = False
if (items is not None) and (hasattr(items, '__len__')):
obj_seq = memo[obj_id][1]
if (len(items) != len(obj_seq)):
seq_diff = True
elif hasattr(obj, "items"): # dict type obj
obj_get = obj_seq.get
for key, item in items.items():
if id_(item) != obj_get(id_(key)) \
or chngd(key, seen, True, False) \
or chngd(item, seen, True, False):
seq_diff = True
break
else:
for i, j in zip(items, obj_seq): # list type obj
if id_(i) != j or chngd(i, seen, True, False):
seq_diff = True
break
seen[obj_id] = changed, seq_diff
if simple:
return changed or seq_diff
return changed, seq_diff
def has_changed(*args, **kwds):
kwds['simple'] = True # ignore simple if passed in
return whats_changed(*args, **kwds)
__import__ = __import__
def _imp(*args, **kwds):
"""
Replaces the default __import__, to allow a module to be memorised
before the user can change it
"""
before = set(sys.modules.keys())
mod = __import__(*args, **kwds)
after = set(sys.modules.keys()).difference(before)
for m in after:
memorise(sys.modules[m])
return mod
builtins.__import__ = _imp
if hasattr(builtins, "_"):
del builtins._
# memorise all already imported modules. This implies that this must be
# imported first for any changes to be recorded
for mod in sys.modules.values():
memorise(mod)
release_gone()

@ -0,0 +1,127 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
# get version numbers, license, and long description
try:
from .info import this_version as __version__
from .info import readme as __doc__, license as __license__
except ImportError:
msg = """First run 'python setup.py build' to build dill."""
raise ImportError(msg)
__author__ = 'Mike McKerns'
__doc__ = """
""" + __doc__
__license__ = """
""" + __license__
from ._dill import dump, dumps, load, loads, dump_session, load_session, \
Pickler, Unpickler, register, copy, pickle, pickles, check, \
HIGHEST_PROTOCOL, DEFAULT_PROTOCOL, PicklingError, UnpicklingError, \
HANDLE_FMODE, CONTENTS_FMODE, FILE_FMODE
from . import source, temp, detect
# get global settings
from .settings import settings
# make sure "trace" is turned off
detect.trace(False)
try:
from importlib import reload
except ImportError:
try:
from imp import reload
except ImportError:
pass
# put the objects in order, if possible
try:
from collections import OrderedDict as odict
except ImportError:
try:
from ordereddict import OrderedDict as odict
except ImportError:
odict = dict
objects = odict()
# local import of dill._objects
#from . import _objects
#objects.update(_objects.succeeds)
#del _objects
# local import of dill.objtypes
from . import objtypes as types
def load_types(pickleable=True, unpickleable=True):
"""load pickleable and/or unpickleable types to ``dill.types``
``dill.types`` is meant to mimic the ``types`` module, providing a
registry of object types. By default, the module is empty (for import
speed purposes). Use the ``load_types`` function to load selected object
types to the ``dill.types`` module.
Args:
pickleable (bool, default=True): if True, load pickleable types.
unpickleable (bool, default=True): if True, load unpickleable types.
Returns:
None
"""
# local import of dill.objects
from . import _objects
if pickleable:
objects.update(_objects.succeeds)
else:
[objects.pop(obj,None) for obj in _objects.succeeds]
if unpickleable:
objects.update(_objects.failures)
else:
[objects.pop(obj,None) for obj in _objects.failures]
objects.update(_objects.registered)
del _objects
# reset contents of types to 'empty'
[types.__dict__.pop(obj) for obj in list(types.__dict__.keys()) \
if obj.find('Type') != -1]
# add corresponding types from objects to types
reload(types)
def extend(use_dill=True):
'''add (or remove) dill types to/from the pickle registry
by default, ``dill`` populates its types to ``pickle.Pickler.dispatch``.
Thus, all ``dill`` types are available upon calling ``'import pickle'``.
To drop all ``dill`` types from the ``pickle`` dispatch, *use_dill=False*.
Args:
use_dill (bool, default=True): if True, extend the dispatch table.
Returns:
None
'''
from ._dill import _revert_extension, _extend
if use_dill: _extend()
else: _revert_extension()
return
extend()
def license():
"""print license"""
print (__license__)
return
def citation():
"""print citation"""
print (__doc__[-501:-123])
return
del odict
# end of file

File diff suppressed because it is too large Load Diff

@ -0,0 +1,558 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
"""
all Python Standard Library objects (currently: CH 1-15 @ 2.7)
and some other common objects (i.e. numpy.ndarray)
"""
__all__ = ['registered','failures','succeeds']
# helper imports
import warnings; warnings.filterwarnings("ignore", category=DeprecationWarning)
import sys
PY3 = (hex(sys.hexversion) >= '0x30000f0')
if PY3:
import queue as Queue
import dbm as anydbm
else:
import Queue
import anydbm
import sets # deprecated/removed
import mutex # removed
try:
from cStringIO import StringIO # has StringI and StringO types
except ImportError: # only has StringIO type
if PY3:
from io import BytesIO as StringIO
else:
from StringIO import StringIO
import re
import array
import collections
import codecs
import struct
import datetime
import calendar
import weakref
import pprint
import decimal
import functools
import itertools
import operator
import tempfile
import shelve
import zlib
import gzip
import zipfile
import tarfile
import xdrlib
import csv
import hashlib
import hmac
import os
import logging
import optparse
#import __hello__
import threading
import socket
import contextlib
try:
import bz2
import sqlite3
if PY3: import dbm.ndbm as dbm
else: import dbm
HAS_ALL = True
except ImportError: # Ubuntu
HAS_ALL = False
try:
#import curses
#from curses import textpad, panel
HAS_CURSES = True
except ImportError: # Windows
HAS_CURSES = False
try:
import ctypes
HAS_CTYPES = True
# if using `pypy`, pythonapi is not found
IS_PYPY = not hasattr(ctypes, 'pythonapi')
except ImportError: # MacPorts
HAS_CTYPES = False
IS_PYPY = False
# helper objects
class _class:
def _method(self):
pass
# @classmethod
# def _clsmethod(cls): #XXX: test me
# pass
# @staticmethod
# def _static(self): #XXX: test me
# pass
class _class2:
def __call__(self):
pass
_instance2 = _class2()
class _newclass(object):
def _method(self):
pass
# @classmethod
# def _clsmethod(cls): #XXX: test me
# pass
# @staticmethod
# def _static(self): #XXX: test me
# pass
class _newclass2(object):
__slots__ = ['descriptor']
def _function(x): yield x
def _function2():
try: raise
except:
from sys import exc_info
e, er, tb = exc_info()
return er, tb
if HAS_CTYPES:
class _Struct(ctypes.Structure):
pass
_Struct._fields_ = [("_field", ctypes.c_int),("next", ctypes.POINTER(_Struct))]
_filedescrip, _tempfile = tempfile.mkstemp('r') # deleted in cleanup
_tmpf = tempfile.TemporaryFile('w')
# put the objects in order, if possible
try:
from collections import OrderedDict as odict
except ImportError:
try:
from ordereddict import OrderedDict as odict
except ImportError:
odict = dict
# objects used by dill for type declaration
registered = d = odict()
# objects dill fails to pickle
failures = x = odict()
# all other type objects
succeeds = a = odict()
# types module (part of CH 8)
a['BooleanType'] = bool(1)
a['BuiltinFunctionType'] = len
a['BuiltinMethodType'] = a['BuiltinFunctionType']
a['BytesType'] = _bytes = codecs.latin_1_encode('\x00')[0] # bytes(1)
a['ClassType'] = _class
a['ComplexType'] = complex(1)
a['DictType'] = _dict = {}
a['DictionaryType'] = a['DictType']
a['FloatType'] = float(1)
a['FunctionType'] = _function
a['InstanceType'] = _instance = _class()
a['IntType'] = _int = int(1)
a['ListType'] = _list = []
a['NoneType'] = None
a['ObjectType'] = object()
a['StringType'] = _str = str(1)
a['TupleType'] = _tuple = ()
a['TypeType'] = type
if PY3:
a['LongType'] = _int
a['UnicodeType'] = _str
else:
a['LongType'] = long(1)
a['UnicodeType'] = unicode(1)
# built-in constants (CH 4)
a['CopyrightType'] = copyright
# built-in types (CH 5)
a['ClassObjectType'] = _newclass # <type 'type'>
a['ClassInstanceType'] = _newclass() # <type 'class'>
a['SetType'] = _set = set()
a['FrozenSetType'] = frozenset()
# built-in exceptions (CH 6)
a['ExceptionType'] = _exception = _function2()[0]
# string services (CH 7)
a['SREPatternType'] = _srepattern = re.compile('')
# data types (CH 8)
a['ArrayType'] = array.array("f")
a['DequeType'] = collections.deque([0])
a['DefaultDictType'] = collections.defaultdict(_function, _dict)
a['TZInfoType'] = datetime.tzinfo()
a['DateTimeType'] = datetime.datetime.today()
a['CalendarType'] = calendar.Calendar()
if not PY3:
a['SetsType'] = sets.Set()
a['ImmutableSetType'] = sets.ImmutableSet()
a['MutexType'] = mutex.mutex()
# numeric and mathematical types (CH 9)
a['DecimalType'] = decimal.Decimal(1)
a['CountType'] = itertools.count(0)
# data compression and archiving (CH 12)
a['TarInfoType'] = tarfile.TarInfo()
# generic operating system services (CH 15)
a['LoggerType'] = logging.getLogger()
a['FormatterType'] = logging.Formatter() # pickle ok
a['FilterType'] = logging.Filter() # pickle ok
a['LogRecordType'] = logging.makeLogRecord(_dict) # pickle ok
a['OptionParserType'] = _oparser = optparse.OptionParser() # pickle ok
a['OptionGroupType'] = optparse.OptionGroup(_oparser,"foo") # pickle ok
a['OptionType'] = optparse.Option('--foo') # pickle ok
if HAS_CTYPES:
a['CCharType'] = _cchar = ctypes.c_char()
a['CWCharType'] = ctypes.c_wchar() # fail == 2.6
a['CByteType'] = ctypes.c_byte()
a['CUByteType'] = ctypes.c_ubyte()
a['CShortType'] = ctypes.c_short()
a['CUShortType'] = ctypes.c_ushort()
a['CIntType'] = ctypes.c_int()
a['CUIntType'] = ctypes.c_uint()
a['CLongType'] = ctypes.c_long()
a['CULongType'] = ctypes.c_ulong()
a['CLongLongType'] = ctypes.c_longlong()
a['CULongLongType'] = ctypes.c_ulonglong()
a['CFloatType'] = ctypes.c_float()
a['CDoubleType'] = ctypes.c_double()
a['CSizeTType'] = ctypes.c_size_t()
a['CLibraryLoaderType'] = ctypes.cdll
a['StructureType'] = _Struct
if not IS_PYPY:
a['BigEndianStructureType'] = ctypes.BigEndianStructure()
#NOTE: also LittleEndianStructureType and UnionType... abstract classes
#NOTE: remember for ctypesobj.contents creates a new python object
#NOTE: ctypes.c_int._objects is memberdescriptor for object's __dict__
#NOTE: base class of all ctypes data types is non-public _CData
try: # python 2.6
import fractions
import number
import io
from io import StringIO as TextIO
# built-in functions (CH 2)
a['ByteArrayType'] = bytearray([1])
# numeric and mathematical types (CH 9)
a['FractionType'] = fractions.Fraction()
a['NumberType'] = numbers.Number()
# generic operating system services (CH 15)
a['IOBaseType'] = io.IOBase()
a['RawIOBaseType'] = io.RawIOBase()
a['TextIOBaseType'] = io.TextIOBase()
a['BufferedIOBaseType'] = io.BufferedIOBase()
a['UnicodeIOType'] = TextIO() # the new StringIO
a['LoggingAdapterType'] = logging.LoggingAdapter(_logger,_dict) # pickle ok
if HAS_CTYPES:
a['CBoolType'] = ctypes.c_bool(1)
a['CLongDoubleType'] = ctypes.c_longdouble()
except ImportError:
pass
try: # python 2.7
import argparse
# data types (CH 8)
a['OrderedDictType'] = collections.OrderedDict(_dict)
a['CounterType'] = collections.Counter(_dict)
if HAS_CTYPES:
a['CSSizeTType'] = ctypes.c_ssize_t()
# generic operating system services (CH 15)
a['NullHandlerType'] = logging.NullHandler() # pickle ok # new 2.7
a['ArgParseFileType'] = argparse.FileType() # pickle ok
except (AttributeError, ImportError):
pass
# -- pickle fails on all below here -----------------------------------------
# types module (part of CH 8)
a['CodeType'] = compile('','','exec')
a['DictProxyType'] = type.__dict__
a['DictProxyType2'] = _newclass.__dict__
a['EllipsisType'] = Ellipsis
a['ClosedFileType'] = open(os.devnull, 'wb', buffering=0).close()
a['GetSetDescriptorType'] = array.array.typecode
a['LambdaType'] = _lambda = lambda x: lambda y: x #XXX: works when not imported!
a['MemberDescriptorType'] = _newclass2.descriptor
if not IS_PYPY:
a['MemberDescriptorType2'] = datetime.timedelta.days
a['MethodType'] = _method = _class()._method #XXX: works when not imported!
a['ModuleType'] = datetime
a['NotImplementedType'] = NotImplemented
a['SliceType'] = slice(1)
a['UnboundMethodType'] = _class._method #XXX: works when not imported!
a['TextWrapperType'] = open(os.devnull, 'r') # same as mode='w','w+','r+'
a['BufferedRandomType'] = open(os.devnull, 'r+b') # same as mode='w+b'
a['BufferedReaderType'] = open(os.devnull, 'rb') # (default: buffering=-1)
a['BufferedWriterType'] = open(os.devnull, 'wb')
try: # oddities: deprecated
from _pyio import open as _open
a['PyTextWrapperType'] = _open(os.devnull, 'r', buffering=-1)
a['PyBufferedRandomType'] = _open(os.devnull, 'r+b', buffering=-1)
a['PyBufferedReaderType'] = _open(os.devnull, 'rb', buffering=-1)
a['PyBufferedWriterType'] = _open(os.devnull, 'wb', buffering=-1)
except ImportError:
pass
# other (concrete) object types
if PY3:
d['CellType'] = (_lambda)(0).__closure__[0]
a['XRangeType'] = _xrange = range(1)
else:
d['CellType'] = (_lambda)(0).func_closure[0]
a['XRangeType'] = _xrange = xrange(1)
if not IS_PYPY:
d['MethodDescriptorType'] = type.__dict__['mro']
d['WrapperDescriptorType'] = type.__repr__
a['WrapperDescriptorType2'] = type.__dict__['__module__']
d['ClassMethodDescriptorType'] = type.__dict__['__prepare__' if PY3 else 'mro']
# built-in functions (CH 2)
if PY3 or IS_PYPY:
_methodwrap = (1).__lt__
else:
_methodwrap = (1).__cmp__
d['MethodWrapperType'] = _methodwrap
a['StaticMethodType'] = staticmethod(_method)
a['ClassMethodType'] = classmethod(_method)
a['PropertyType'] = property()
d['SuperType'] = super(Exception, _exception)
# string services (CH 7)
if PY3:
_in = _bytes
else:
_in = _str
a['InputType'] = _cstrI = StringIO(_in)
a['OutputType'] = _cstrO = StringIO()
# data types (CH 8)
a['WeakKeyDictionaryType'] = weakref.WeakKeyDictionary()
a['WeakValueDictionaryType'] = weakref.WeakValueDictionary()
a['ReferenceType'] = weakref.ref(_instance)
a['DeadReferenceType'] = weakref.ref(_class())
a['ProxyType'] = weakref.proxy(_instance)
a['DeadProxyType'] = weakref.proxy(_class())
a['CallableProxyType'] = weakref.proxy(_instance2)
a['DeadCallableProxyType'] = weakref.proxy(_class2())
a['QueueType'] = Queue.Queue()
# numeric and mathematical types (CH 9)
d['PartialType'] = functools.partial(int,base=2)
if PY3:
a['IzipType'] = zip('0','1')
else:
a['IzipType'] = itertools.izip('0','1')
a['ChainType'] = itertools.chain('0','1')
d['ItemGetterType'] = operator.itemgetter(0)
d['AttrGetterType'] = operator.attrgetter('__repr__')
# file and directory access (CH 10)
if PY3: _fileW = _cstrO
else: _fileW = _tmpf
# data persistence (CH 11)
if HAS_ALL:
a['ConnectionType'] = _conn = sqlite3.connect(':memory:')
a['CursorType'] = _conn.cursor()
a['ShelveType'] = shelve.Shelf({})
# data compression and archiving (CH 12)
if HAS_ALL:
if (hex(sys.hexversion) < '0x2070ef0') or PY3:
a['BZ2FileType'] = bz2.BZ2File(os.devnull) #FIXME: fail >= 3.3, 2.7.14
a['BZ2CompressorType'] = bz2.BZ2Compressor()
a['BZ2DecompressorType'] = bz2.BZ2Decompressor()
#a['ZipFileType'] = _zip = zipfile.ZipFile(os.devnull,'w') #FIXME: fail >= 3.2
#_zip.write(_tempfile,'x') [causes annoying warning/error printed on import]
#a['ZipInfoType'] = _zip.getinfo('x')
a['TarFileType'] = tarfile.open(fileobj=_fileW,mode='w')
# file formats (CH 13)
a['DialectType'] = csv.get_dialect('excel')
a['PackerType'] = xdrlib.Packer()
# optional operating system services (CH 16)
a['LockType'] = threading.Lock()
a['RLockType'] = threading.RLock()
# generic operating system services (CH 15) # also closed/open and r/w/etc...
a['NamedLoggerType'] = _logger = logging.getLogger(__name__) #FIXME: fail >= 3.2 and <= 2.6
#a['FrozenModuleType'] = __hello__ #FIXME: prints "Hello world..."
# interprocess communication (CH 17)
if PY3:
a['SocketType'] = _socket = socket.socket() #FIXME: fail >= 3.3
a['SocketPairType'] = socket.socketpair()[0] #FIXME: fail >= 3.3
else:
a['SocketType'] = _socket = socket.socket()
a['SocketPairType'] = _socket._sock
# python runtime services (CH 27)
if PY3:
a['GeneratorContextManagerType'] = contextlib.contextmanager(max)([1])
else:
a['GeneratorContextManagerType'] = contextlib.GeneratorContextManager(max)
try: # ipython
__IPYTHON__ is True # is ipython
except NameError:
# built-in constants (CH 4)
a['QuitterType'] = quit
d['ExitType'] = a['QuitterType']
try: # numpy #FIXME: slow... 0.05 to 0.1 sec to import numpy
from numpy import ufunc as _numpy_ufunc
from numpy import array as _numpy_array
from numpy import int32 as _numpy_int32
a['NumpyUfuncType'] = _numpy_ufunc
a['NumpyArrayType'] = _numpy_array
a['NumpyInt32Type'] = _numpy_int32
except ImportError:
pass
try: # python 2.6
# numeric and mathematical types (CH 9)
a['ProductType'] = itertools.product('0','1')
# generic operating system services (CH 15)
a['FileHandlerType'] = logging.FileHandler(os.devnull) #FIXME: fail >= 3.2 and <= 2.6
a['RotatingFileHandlerType'] = logging.handlers.RotatingFileHandler(os.devnull)
a['SocketHandlerType'] = logging.handlers.SocketHandler('localhost',514)
a['MemoryHandlerType'] = logging.handlers.MemoryHandler(1)
except AttributeError:
pass
try: # python 2.7
# data types (CH 8)
a['WeakSetType'] = weakref.WeakSet() # 2.7
# # generic operating system services (CH 15) [errors when dill is imported]
# a['ArgumentParserType'] = _parser = argparse.ArgumentParser('PROG')
# a['NamespaceType'] = _parser.parse_args() # pickle ok
# a['SubParsersActionType'] = _parser.add_subparsers()
# a['MutuallyExclusiveGroupType'] = _parser.add_mutually_exclusive_group()
# a['ArgumentGroupType'] = _parser.add_argument_group()
except AttributeError:
pass
# -- dill fails in some versions below here ---------------------------------
# types module (part of CH 8)
a['FileType'] = open(os.devnull, 'rb', buffering=0) # same 'wb','wb+','rb+'
# FIXME: FileType fails >= 3.1
# built-in functions (CH 2)
a['ListIteratorType'] = iter(_list) # empty vs non-empty FIXME: fail < 3.2
a['TupleIteratorType']= iter(_tuple) # empty vs non-empty FIXME: fail < 3.2
a['XRangeIteratorType'] = iter(_xrange) # empty vs non-empty FIXME: fail < 3.2
# data types (CH 8)
a['PrettyPrinterType'] = pprint.PrettyPrinter() #FIXME: fail >= 3.2 and == 2.5
# numeric and mathematical types (CH 9)
a['CycleType'] = itertools.cycle('0') #FIXME: fail < 3.2
# file and directory access (CH 10)
a['TemporaryFileType'] = _tmpf #FIXME: fail >= 3.2 and == 2.5
# data compression and archiving (CH 12)
a['GzipFileType'] = gzip.GzipFile(fileobj=_fileW) #FIXME: fail > 3.2 and <= 2.6
# generic operating system services (CH 15)
a['StreamHandlerType'] = logging.StreamHandler() #FIXME: fail >= 3.2 and == 2.5
try: # python 2.6
# numeric and mathematical types (CH 9)
a['PermutationsType'] = itertools.permutations('0') #FIXME: fail < 3.2
a['CombinationsType'] = itertools.combinations('0',1) #FIXME: fail < 3.2
except AttributeError:
pass
try: # python 2.7
# numeric and mathematical types (CH 9)
a['RepeatType'] = itertools.repeat(0) #FIXME: fail < 3.2
a['CompressType'] = itertools.compress('0',[1]) #FIXME: fail < 3.2
#XXX: ...and etc
except AttributeError:
pass
# -- dill fails on all below here -------------------------------------------
# types module (part of CH 8)
x['GeneratorType'] = _generator = _function(1) #XXX: priority
x['FrameType'] = _generator.gi_frame #XXX: inspect.currentframe()
x['TracebackType'] = _function2()[1] #(see: inspect.getouterframes,getframeinfo)
# other (concrete) object types
# (also: Capsule / CObject ?)
# built-in functions (CH 2)
x['SetIteratorType'] = iter(_set) #XXX: empty vs non-empty
# built-in types (CH 5)
if PY3:
x['DictionaryItemIteratorType'] = iter(type.__dict__.items())
x['DictionaryKeyIteratorType'] = iter(type.__dict__.keys())
x['DictionaryValueIteratorType'] = iter(type.__dict__.values())
else:
x['DictionaryItemIteratorType'] = type.__dict__.iteritems()
x['DictionaryKeyIteratorType'] = type.__dict__.iterkeys()
x['DictionaryValueIteratorType'] = type.__dict__.itervalues()
# string services (CH 7)
x['StructType'] = struct.Struct('c')
x['CallableIteratorType'] = _srepattern.finditer('')
x['SREMatchType'] = _srepattern.match('')
x['SREScannerType'] = _srepattern.scanner('')
x['StreamReader'] = codecs.StreamReader(_cstrI) #XXX: ... and etc
# python object persistence (CH 11)
# x['DbShelveType'] = shelve.open('foo','n')#,protocol=2) #XXX: delete foo
if HAS_ALL:
x['DbmType'] = dbm.open(_tempfile,'n')
# x['DbCursorType'] = _dbcursor = anydbm.open('foo','n') #XXX: delete foo
# x['DbType'] = _dbcursor.db
# data compression and archiving (CH 12)
x['ZlibCompressType'] = zlib.compressobj()
x['ZlibDecompressType'] = zlib.decompressobj()
# file formats (CH 13)
x['CSVReaderType'] = csv.reader(_cstrI)
x['CSVWriterType'] = csv.writer(_cstrO)
x['CSVDictReaderType'] = csv.DictReader(_cstrI)
x['CSVDictWriterType'] = csv.DictWriter(_cstrO,{})
# cryptographic services (CH 14)
x['HashType'] = hashlib.md5()
if (hex(sys.hexversion) < '0x30800a1'):
x['HMACType'] = hmac.new(_in)
else:
x['HMACType'] = hmac.new(_in, digestmod='md5')
# generic operating system services (CH 15)
if HAS_CURSES: pass
#x['CursesWindowType'] = _curwin = curses.initscr() #FIXME: messes up tty
#x['CursesTextPadType'] = textpad.Textbox(_curwin)
#x['CursesPanelType'] = panel.new_panel(_curwin)
if HAS_CTYPES:
x['CCharPType'] = ctypes.c_char_p()
x['CWCharPType'] = ctypes.c_wchar_p()
x['CVoidPType'] = ctypes.c_void_p()
if sys.platform[:3] == 'win':
x['CDLLType'] = _cdll = ctypes.cdll.msvcrt
else:
x['CDLLType'] = _cdll = ctypes.CDLL(None)
if not IS_PYPY:
x['PyDLLType'] = _pydll = ctypes.pythonapi
x['FuncPtrType'] = _cdll._FuncPtr()
x['CCharArrayType'] = ctypes.create_string_buffer(1)
x['CWCharArrayType'] = ctypes.create_unicode_buffer(1)
x['CParamType'] = ctypes.byref(_cchar)
x['LPCCharType'] = ctypes.pointer(_cchar)
x['LPCCharObjType'] = _lpchar = ctypes.POINTER(ctypes.c_char)
x['NullPtrType'] = _lpchar()
x['NullPyObjectType'] = ctypes.py_object()
x['PyObjectType'] = ctypes.py_object(lambda :None)
x['FieldType'] = _field = _Struct._field
x['CFUNCTYPEType'] = _cfunc = ctypes.CFUNCTYPE(ctypes.c_char)
x['CFunctionType'] = _cfunc(str)
try: # python 2.6
# numeric and mathematical types (CH 9)
x['MethodCallerType'] = operator.methodcaller('mro') # 2.6
except AttributeError:
pass
try: # python 2.7
# built-in types (CH 5)
x['MemoryType'] = memoryview(_in) # 2.7
x['MemoryType2'] = memoryview(bytearray(_in)) # 2.7
if PY3:
x['DictItemsType'] = _dict.items() # 2.7
x['DictKeysType'] = _dict.keys() # 2.7
x['DictValuesType'] = _dict.values() # 2.7
else:
x['DictItemsType'] = _dict.viewitems() # 2.7
x['DictKeysType'] = _dict.viewkeys() # 2.7
x['DictValuesType'] = _dict.viewvalues() # 2.7
# generic operating system services (CH 15)
x['RawTextHelpFormatterType'] = argparse.RawTextHelpFormatter('PROG')
x['RawDescriptionHelpFormatterType'] = argparse.RawDescriptionHelpFormatter('PROG')
x['ArgDefaultsHelpFormatterType'] = argparse.ArgumentDefaultsHelpFormatter('PROG')
except NameError:
pass
try: # python 2.7 (and not 3.1)
x['CmpKeyType'] = _cmpkey = functools.cmp_to_key(_methodwrap) # 2.7, >=3.2
x['CmpKeyObjType'] = _cmpkey('0') #2.7, >=3.2
except AttributeError:
pass
if PY3: # oddities: removed, etc
x['BufferType'] = x['MemoryType']
else:
x['BufferType'] = buffer('')
# -- cleanup ----------------------------------------------------------------
a.update(d) # registered also succeed
if sys.platform[:3] == 'win':
os.close(_filedescrip) # required on win32
os.remove(_tempfile)
# EOF

@ -0,0 +1,308 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
"""
Methods for detecting objects leading to pickling failures.
"""
import dis
from inspect import ismethod, isfunction, istraceback, isframe, iscode
from .pointers import parent, reference, at, parents, children
from ._dill import _trace as trace
from ._dill import PY3
__all__ = ['baditems','badobjects','badtypes','code','errors','freevars',
'getmodule','globalvars','nestedcode','nestedglobals','outermost',
'referredglobals','referrednested','trace','varnames']
def getmodule(object, _filename=None, force=False):
"""get the module of the object"""
from inspect import getmodule as getmod
module = getmod(object, _filename)
if module or not force: return module
if PY3: builtins = 'builtins'
else: builtins = '__builtin__'
builtins = __import__(builtins)
from .source import getname
name = getname(object, force=True)
return builtins if name in vars(builtins).keys() else None
def outermost(func): # is analogous to getsource(func,enclosing=True)
"""get outermost enclosing object (i.e. the outer function in a closure)
NOTE: this is the object-equivalent of getsource(func, enclosing=True)
"""
if PY3:
if ismethod(func):
_globals = func.__func__.__globals__ or {}
elif isfunction(func):
_globals = func.__globals__ or {}
else:
return #XXX: or raise? no matches
_globals = _globals.items()
else:
if ismethod(func):
_globals = func.im_func.func_globals or {}
elif isfunction(func):
_globals = func.func_globals or {}
else:
return #XXX: or raise? no matches
_globals = _globals.iteritems()
# get the enclosing source
from .source import getsourcelines
try: lines,lnum = getsourcelines(func, enclosing=True)
except: #TypeError, IOError
lines,lnum = [],None
code = ''.join(lines)
# get all possible names,objects that are named in the enclosing source
_locals = ((name,obj) for (name,obj) in _globals if name in code)
# now only save the objects that generate the enclosing block
for name,obj in _locals: #XXX: don't really need 'name'
try:
if getsourcelines(obj) == (lines,lnum): return obj
except: #TypeError, IOError
pass
return #XXX: or raise? no matches
def nestedcode(func, recurse=True): #XXX: or return dict of {co_name: co} ?
"""get the code objects for any nested functions (e.g. in a closure)"""
func = code(func)
if not iscode(func): return [] #XXX: or raise? no matches
nested = set()
for co in func.co_consts:
if co is None: continue
co = code(co)
if co:
nested.add(co)
if recurse: nested |= set(nestedcode(co, recurse=True))
return list(nested)
def code(func):
'''get the code object for the given function or method
NOTE: use dill.source.getsource(CODEOBJ) to get the source code
'''
if PY3:
im_func = '__func__'
func_code = '__code__'
else:
im_func = 'im_func'
func_code = 'func_code'
if ismethod(func): func = getattr(func, im_func)
if isfunction(func): func = getattr(func, func_code)
if istraceback(func): func = func.tb_frame
if isframe(func): func = func.f_code
if iscode(func): return func
return
#XXX: ugly: parse dis.dis for name after "<code object" in line and in globals?
def referrednested(func, recurse=True): #XXX: return dict of {__name__: obj} ?
"""get functions defined inside of func (e.g. inner functions in a closure)
NOTE: results may differ if the function has been executed or not.
If len(nestedcode(func)) > len(referrednested(func)), try calling func().
If possible, python builds code objects, but delays building functions
until func() is called.
"""
if PY3:
att1 = '__code__'
att0 = '__func__'
else:
att1 = 'func_code' # functions
att0 = 'im_func' # methods
import gc
funcs = set()
# get the code objects, and try to track down by referrence
for co in nestedcode(func, recurse):
# look for function objects that refer to the code object
for obj in gc.get_referrers(co):
# get methods
_ = getattr(obj, att0, None) # ismethod
if getattr(_, att1, None) is co: funcs.add(obj)
# get functions
elif getattr(obj, att1, None) is co: funcs.add(obj)
# get frame objects
elif getattr(obj, 'f_code', None) is co: funcs.add(obj)
# get code objects
elif hasattr(obj, 'co_code') and obj is co: funcs.add(obj)
# frameobjs => func.func_code.co_varnames not in func.func_code.co_cellvars
# funcobjs => func.func_code.co_cellvars not in func.func_code.co_varnames
# frameobjs are not found, however funcobjs are...
# (see: test_mixins.quad ... and test_mixins.wtf)
# after execution, code objects get compiled, and then may be found by gc
return list(funcs)
def freevars(func):
"""get objects defined in enclosing code that are referred to by func
returns a dict of {name:object}"""
if PY3:
im_func = '__func__'
func_code = '__code__'
func_closure = '__closure__'
else:
im_func = 'im_func'
func_code = 'func_code'
func_closure = 'func_closure'
if ismethod(func): func = getattr(func, im_func)
if isfunction(func):
closures = getattr(func, func_closure) or ()
func = getattr(func, func_code).co_freevars # get freevars
else:
return {}
return dict((name,c.cell_contents) for (name,c) in zip(func,closures))
# thanks to Davies Liu for recursion of globals
def nestedglobals(func, recurse=True):
"""get the names of any globals found within func"""
func = code(func)
if func is None: return list()
from .temp import capture
names = set()
with capture('stdout') as out:
dis.dis(func) #XXX: dis.dis(None) disassembles last traceback
for line in out.getvalue().splitlines():
if '_GLOBAL' in line:
name = line.split('(')[-1].split(')')[0]
names.add(name)
for co in getattr(func, 'co_consts', tuple()):
if co and recurse and iscode(co):
names.update(nestedglobals(co, recurse=True))
return list(names)
def referredglobals(func, recurse=True, builtin=False):
"""get the names of objects in the global scope referred to by func"""
return globalvars(func, recurse, builtin).keys()
def globalvars(func, recurse=True, builtin=False):
"""get objects defined in global scope that are referred to by func
return a dict of {name:object}"""
if PY3:
im_func = '__func__'
func_code = '__code__'
func_globals = '__globals__'
func_closure = '__closure__'
else:
im_func = 'im_func'
func_code = 'func_code'
func_globals = 'func_globals'
func_closure = 'func_closure'
if ismethod(func): func = getattr(func, im_func)
if isfunction(func):
globs = vars(getmodule(sum)).copy() if builtin else {}
# get references from within closure
orig_func, func = func, set()
for obj in getattr(orig_func, func_closure) or {}:
_vars = globalvars(obj.cell_contents, recurse, builtin) or {}
func.update(_vars) #XXX: (above) be wary of infinte recursion?
globs.update(_vars)
# get globals
globs.update(getattr(orig_func, func_globals) or {})
# get names of references
if not recurse:
func.update(getattr(orig_func, func_code).co_names)
else:
func.update(nestedglobals(getattr(orig_func, func_code)))
# find globals for all entries of func
for key in func.copy(): #XXX: unnecessary...?
nested_func = globs.get(key)
if nested_func is orig_func:
#func.remove(key) if key in func else None
continue #XXX: globalvars(func, False)?
func.update(globalvars(nested_func, True, builtin))
elif iscode(func):
globs = vars(getmodule(sum)).copy() if builtin else {}
#globs.update(globals())
if not recurse:
func = func.co_names # get names
else:
orig_func = func.co_name # to stop infinite recursion
func = set(nestedglobals(func))
# find globals for all entries of func
for key in func.copy(): #XXX: unnecessary...?
if key is orig_func:
#func.remove(key) if key in func else None
continue #XXX: globalvars(func, False)?
nested_func = globs.get(key)
func.update(globalvars(nested_func, True, builtin))
else:
return {}
#NOTE: if name not in func_globals, then we skip it...
return dict((name,globs[name]) for name in func if name in globs)
def varnames(func):
"""get names of variables defined by func
returns a tuple (local vars, local vars referrenced by nested functions)"""
func = code(func)
if not iscode(func):
return () #XXX: better ((),())? or None?
return func.co_varnames, func.co_cellvars
def baditems(obj, exact=False, safe=False): #XXX: obj=globals() ?
"""get items in object that fail to pickle"""
if not hasattr(obj,'__iter__'): # is not iterable
return [j for j in (badobjects(obj,0,exact,safe),) if j is not None]
obj = obj.values() if getattr(obj,'values',None) else obj
_obj = [] # can't use a set, as items may be unhashable
[_obj.append(badobjects(i,0,exact,safe)) for i in obj if i not in _obj]
return [j for j in _obj if j is not None]
def badobjects(obj, depth=0, exact=False, safe=False):
"""get objects that fail to pickle"""
from dill import pickles
if not depth:
if pickles(obj,exact,safe): return None
return obj
return dict(((attr, badobjects(getattr(obj,attr),depth-1,exact,safe)) \
for attr in dir(obj) if not pickles(getattr(obj,attr),exact,safe)))
def badtypes(obj, depth=0, exact=False, safe=False):
"""get types for objects that fail to pickle"""
from dill import pickles
if not depth:
if pickles(obj,exact,safe): return None
return type(obj)
return dict(((attr, badtypes(getattr(obj,attr),depth-1,exact,safe)) \
for attr in dir(obj) if not pickles(getattr(obj,attr),exact,safe)))
def errors(obj, depth=0, exact=False, safe=False):
"""get errors for objects that fail to pickle"""
from dill import pickles, copy
if not depth:
try:
pik = copy(obj)
if exact:
assert pik == obj, \
"Unpickling produces %s instead of %s" % (pik,obj)
assert type(pik) == type(obj), \
"Unpickling produces %s instead of %s" % (type(pik),type(obj))
return None
except Exception:
import sys
return sys.exc_info()[1]
_dict = {}
for attr in dir(obj):
try:
_attr = getattr(obj,attr)
except Exception:
import sys
_dict[attr] = sys.exc_info()[1]
continue
if not pickles(_attr,exact,safe):
_dict[attr] = errors(_attr,depth-1,exact,safe)
return _dict
# EOF

@ -0,0 +1,202 @@
# THIS FILE GENERATED FROM SETUP.PY
this_version = '0.3.1.1'
stable_version = '0.3.1.1'
readme = '''-----------------------------
dill: serialize all of python
-----------------------------
About Dill
==========
``dill`` extends python's ``pickle`` module for serializing and de-serializing
python objects to the majority of the built-in python types. Serialization
is the process of converting an object to a byte stream, and the inverse
of which is converting a byte stream back to on python object hierarchy.
``dill`` provides the user the same interface as the ``pickle`` module, and
also includes some additional features. In addition to pickling python
objects, ``dill`` provides the ability to save the state of an interpreter
session in a single command. Hence, it would be feasable to save a
interpreter session, close the interpreter, ship the pickled file to
another computer, open a new interpreter, unpickle the session and
thus continue from the 'saved' state of the original interpreter
session.
``dill`` can be used to store python objects to a file, but the primary
usage is to send python objects across the network as a byte stream.
``dill`` is quite flexible, and allows arbitrary user defined classes
and functions to be serialized. Thus ``dill`` is not intended to be
secure against erroneously or maliciously constructed data. It is
left to the user to decide whether the data they unpickle is from
a trustworthy source.
``dill`` is part of ``pathos``, a python framework for heterogeneous computing.
``dill`` is in active development, so any user feedback, bug reports, comments,
or suggestions are highly appreciated. A list of known issues is maintained
at http://trac.mystic.cacr.caltech.edu/project/pathos/query.html, with a public
ticket list at https://github.com/uqfoundation/dill/issues.
Major Features
==============
``dill`` can pickle the following standard types:
- none, type, bool, int, long, float, complex, str, unicode,
- tuple, list, dict, file, buffer, builtin,
- both old and new style classes,
- instances of old and new style classes,
- set, frozenset, array, functions, exceptions
``dill`` can also pickle more 'exotic' standard types:
- functions with yields, nested functions, lambdas,
- cell, method, unboundmethod, module, code, methodwrapper,
- dictproxy, methoddescriptor, getsetdescriptor, memberdescriptor,
- wrapperdescriptor, xrange, slice,
- notimplemented, ellipsis, quit
``dill`` cannot yet pickle these standard types:
- frame, generator, traceback
``dill`` also provides the capability to:
- save and load python interpreter sessions
- save and extract the source code from functions and classes
- interactively diagnose pickling errors
Current Release
===============
This documentation is for version ``dill-0.3.1.1``.
The latest released version of ``dill`` is available from:
https://pypi.org/project/dill
``dill`` is distributed under a 3-clause BSD license.
>>> import dill
>>> print (dill.license())
Development Version
===================
You can get the latest development version with all the shiny new features at:
https://github.com/uqfoundation
If you have a new contribution, please submit a pull request.
Installation
============
``dill`` is packaged to install from source, so you must
download the tarball, unzip, and run the installer::
[download]
$ tar -xvzf dill-0.3.1.1.tar.gz
$ cd dill-0.3.1.1
$ python setup py build
$ python setup py install
You will be warned of any missing dependencies and/or settings
after you run the "build" step above.
Alternately, ``dill`` can be installed with ``pip`` or ``easy_install``::
$ pip install dill
Requirements
============
``dill`` requires:
- ``python``, **version >= 2.6** or **version >= 3.1**, or ``pypy``
Optional requirements:
- ``setuptools``, **version >= 0.6**
- ``pyreadline``, **version >= 1.7.1** (on windows)
- ``objgraph``, **version >= 1.7.2**
More Information
================
Probably the best way to get started is to look at the documentation at
http://dill.rtfd.io. Also see ``dill.tests`` for a set of scripts that
demonstrate how ``dill`` can serialize different python objects. You can
run the test suite with ``python -m dill.tests``. The contents of any
pickle file can be examined with ``undill``. As ``dill`` conforms to
the ``pickle`` interface, the examples and documentation found at
http://docs.python.org/library/pickle.html also apply to ``dill``
if one will ``import dill as pickle``. The source code is also generally
well documented, so further questions may be resolved by inspecting the
code itself. Please feel free to submit a ticket on github, or ask a
question on stackoverflow (**@Mike McKerns**).
If you would like to share how you use ``dill`` in your work, please send
an email (to **mmckerns at uqfoundation dot org**).
Citation
========
If you use ``dill`` to do research that leads to publication, we ask that you
acknowledge use of ``dill`` by citing the following in your publication::
M.M. McKerns, L. Strand, T. Sullivan, A. Fang, M.A.G. Aivazis,
"Building a framework for predictive science", Proceedings of
the 10th Python in Science Conference, 2011;
http://arxiv.org/pdf/1202.1056
Michael McKerns and Michael Aivazis,
"pathos: a framework for heterogeneous computing", 2010- ;
http://trac.mystic.cacr.caltech.edu/project/pathos
Please see http://trac.mystic.cacr.caltech.edu/project/pathos or
http://arxiv.org/pdf/1202.1056 for further information.
'''
license = '''Copyright (c) 2004-2016 California Institute of Technology.
Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
All rights reserved.
This software is available subject to the conditions and terms laid
out below. By downloading and using this software you are agreeing
to the following conditions.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met::
- Redistribution of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistribution in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentations and/or other materials provided with the distribution.
- Neither the name of the California Institute of Technology nor
the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''

@ -0,0 +1,24 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
"""
all Python Standard Library object types (currently: CH 1-15 @ 2.7)
and some other common object types (i.e. numpy.ndarray)
to load more objects and types, use dill.load_types()
"""
# non-local import of dill.objects
from dill import objects
for _type in objects.keys():
exec("%s = type(objects['%s'])" % (_type,_type))
del objects
try:
del _type
except NameError:
pass

@ -0,0 +1,122 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
__all__ = ['parent', 'reference', 'at', 'parents', 'children']
import gc
import sys
from ._dill import _proxy_helper as reference
from ._dill import _locate_object as at
def parent(obj, objtype, ignore=()):
"""
>>> listiter = iter([4,5,6,7])
>>> obj = parent(listiter, list)
>>> obj == [4,5,6,7] # actually 'is', but don't have handle any longer
True
NOTE: objtype can be a single type (e.g. int or list) or a tuple of types.
WARNING: if obj is a sequence (e.g. list), may produce unexpected results.
Parent finds *one* parent (e.g. the last member of the sequence).
"""
depth = 1 #XXX: always looking for the parent (only, right?)
chain = parents(obj, objtype, depth, ignore)
parent = chain.pop()
if parent is obj:
return None
return parent
def parents(obj, objtype, depth=1, ignore=()): #XXX: objtype=object ?
"""Find the chain of referents for obj. Chain will end with obj.
objtype: an object type or tuple of types to search for
depth: search depth (e.g. depth=2 is 'grandparents')
ignore: an object or tuple of objects to ignore in the search
"""
edge_func = gc.get_referents # looking for refs, not back_refs
predicate = lambda x: isinstance(x, objtype) # looking for parent type
#if objtype is None: predicate = lambda x: True #XXX: in obj.mro() ?
ignore = (ignore,) if not hasattr(ignore, '__len__') else ignore
ignore = (id(obj) for obj in ignore)
chain = find_chain(obj, predicate, edge_func, depth)[::-1]
#XXX: should pop off obj... ?
return chain
def children(obj, objtype, depth=1, ignore=()): #XXX: objtype=object ?
"""Find the chain of referrers for obj. Chain will start with obj.
objtype: an object type or tuple of types to search for
depth: search depth (e.g. depth=2 is 'grandchildren')
ignore: an object or tuple of objects to ignore in the search
NOTE: a common thing to ignore is all globals, 'ignore=(globals(),)'
NOTE: repeated calls may yield different results, as python stores
the last value in the special variable '_'; thus, it is often good
to execute something to replace '_' (e.g. >>> 1+1).
"""
edge_func = gc.get_referrers # looking for back_refs, not refs
predicate = lambda x: isinstance(x, objtype) # looking for child type
#if objtype is None: predicate = lambda x: True #XXX: in obj.mro() ?
ignore = (ignore,) if not hasattr(ignore, '__len__') else ignore
ignore = (id(obj) for obj in ignore)
chain = find_chain(obj, predicate, edge_func, depth, ignore)
#XXX: should pop off obj... ?
return chain
# more generic helper function (cut-n-paste from objgraph)
# Source at http://mg.pov.lt/objgraph/
# Copyright (c) 2008-2010 Marius Gedminas <marius@pov.lt>
# Copyright (c) 2010 Stefano Rivera <stefano@rivera.za.net>
# Released under the MIT licence (see objgraph/objgrah.py)
def find_chain(obj, predicate, edge_func, max_depth=20, extra_ignore=()):
queue = [obj]
depth = {id(obj): 0}
parent = {id(obj): None}
ignore = set(extra_ignore)
ignore.add(id(extra_ignore))
ignore.add(id(queue))
ignore.add(id(depth))
ignore.add(id(parent))
ignore.add(id(ignore))
ignore.add(id(sys._getframe())) # this function
ignore.add(id(sys._getframe(1))) # find_chain/find_backref_chain, likely
gc.collect()
while queue:
target = queue.pop(0)
if predicate(target):
chain = [target]
while parent[id(target)] is not None:
target = parent[id(target)]
chain.append(target)
return chain
tdepth = depth[id(target)]
if tdepth < max_depth:
referrers = edge_func(target)
ignore.add(id(referrers))
for source in referrers:
if id(source) in ignore:
continue
if id(source) not in depth:
depth[id(source)] = tdepth + 1
parent[id(source)] = target
queue.append(source)
return [obj] # not found
# backward compatability
refobject = at
# EOF

@ -0,0 +1,28 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
"""
global settings for Pickler
"""
try:
from pickle import DEFAULT_PROTOCOL
except ImportError:
from pickle import HIGHEST_PROTOCOL as DEFAULT_PROTOCOL
settings = {
#'main' : None,
'protocol' : DEFAULT_PROTOCOL,
'byref' : False,
#'strictio' : False,
'fmode' : 0, #HANDLE_FMODE
'recurse' : False,
'ignore' : False,
}
del DEFAULT_PROTOCOL

File diff suppressed because it is too large Load Diff

@ -0,0 +1,263 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
"""
Methods for serialized objects (or source code) stored in temporary files
and file-like objects.
"""
#XXX: better instead to have functions write to any given file-like object ?
#XXX: currently, all file-like objects are created by the function...
__all__ = ['dump_source', 'dump', 'dumpIO_source', 'dumpIO',\
'load_source', 'load', 'loadIO_source', 'loadIO',\
'capture']
import contextlib
from ._dill import PY3
@contextlib.contextmanager
def capture(stream='stdout'):
"""builds a context that temporarily replaces the given stream name
>>> with capture('stdout') as out:
... print "foo!"
...
>>> print out.getvalue()
foo!
"""
import sys
if PY3:
from io import StringIO
else:
from StringIO import StringIO
orig = getattr(sys, stream)
setattr(sys, stream, StringIO())
try:
yield getattr(sys, stream)
finally:
setattr(sys, stream, orig)
def b(x): # deal with b'foo' versus 'foo'
import codecs
return codecs.latin_1_encode(x)[0]
def load_source(file, **kwds):
"""load an object that was stored with dill.temp.dump_source
file: filehandle
alias: string name of stored object
mode: mode to open the file, one of: {'r', 'rb'}
>>> f = lambda x: x**2
>>> pyfile = dill.temp.dump_source(f, alias='_f')
>>> _f = dill.temp.load_source(pyfile)
>>> _f(4)
16
"""
alias = kwds.pop('alias', None)
mode = kwds.pop('mode', 'r')
fname = getattr(file, 'name', file) # fname=file.name or fname=file (if str)
source = open(fname, mode=mode, **kwds).read()
if not alias:
tag = source.strip().splitlines()[-1].split()
if tag[0] != '#NAME:':
stub = source.splitlines()[0]
raise IOError("unknown name for code: %s" % stub)
alias = tag[-1]
local = {}
exec(source, local)
_ = eval("%s" % alias, local)
return _
def dump_source(object, **kwds):
"""write object source to a NamedTemporaryFile (instead of dill.dump)
Loads with "import" or "dill.temp.load_source". Returns the filehandle.
>>> f = lambda x: x**2
>>> pyfile = dill.temp.dump_source(f, alias='_f')
>>> _f = dill.temp.load_source(pyfile)
>>> _f(4)
16
>>> f = lambda x: x**2
>>> pyfile = dill.temp.dump_source(f, dir='.')
>>> modulename = os.path.basename(pyfile.name).split('.py')[0]
>>> exec('from %s import f as _f' % modulename)
>>> _f(4)
16
Optional kwds:
If 'alias' is specified, the object will be renamed to the given string.
If 'prefix' is specified, the file name will begin with that prefix,
otherwise a default prefix is used.
If 'dir' is specified, the file will be created in that directory,
otherwise a default directory is used.
If 'text' is specified and true, the file is opened in text
mode. Else (the default) the file is opened in binary mode. On
some operating systems, this makes no difference.
NOTE: Keep the return value for as long as you want your file to exist !
""" #XXX: write a "load_source"?
from .source import importable, getname
import tempfile
kwds.pop('suffix', '') # this is *always* '.py'
alias = kwds.pop('alias', '') #XXX: include an alias so a name is known
name = str(alias) or getname(object)
name = "\n#NAME: %s\n" % name
#XXX: assumes kwds['dir'] is writable and on $PYTHONPATH
file = tempfile.NamedTemporaryFile(suffix='.py', **kwds)
file.write(b(''.join([importable(object, alias=alias),name])))
file.flush()
return file
def load(file, **kwds):
"""load an object that was stored with dill.temp.dump
file: filehandle
mode: mode to open the file, one of: {'r', 'rb'}
>>> dumpfile = dill.temp.dump([1, 2, 3, 4, 5])
>>> dill.temp.load(dumpfile)
[1, 2, 3, 4, 5]
"""
import dill as pickle
mode = kwds.pop('mode', 'rb')
name = getattr(file, 'name', file) # name=file.name or name=file (if str)
return pickle.load(open(name, mode=mode, **kwds))
def dump(object, **kwds):
"""dill.dump of object to a NamedTemporaryFile.
Loads with "dill.temp.load". Returns the filehandle.
>>> dumpfile = dill.temp.dump([1, 2, 3, 4, 5])
>>> dill.temp.load(dumpfile)
[1, 2, 3, 4, 5]
Optional kwds:
If 'suffix' is specified, the file name will end with that suffix,
otherwise there will be no suffix.
If 'prefix' is specified, the file name will begin with that prefix,
otherwise a default prefix is used.
If 'dir' is specified, the file will be created in that directory,
otherwise a default directory is used.
If 'text' is specified and true, the file is opened in text
mode. Else (the default) the file is opened in binary mode. On
some operating systems, this makes no difference.
NOTE: Keep the return value for as long as you want your file to exist !
"""
import dill as pickle
import tempfile
file = tempfile.NamedTemporaryFile(**kwds)
pickle.dump(object, file)
file.flush()
return file
def loadIO(buffer, **kwds):
"""load an object that was stored with dill.temp.dumpIO
buffer: buffer object
>>> dumpfile = dill.temp.dumpIO([1, 2, 3, 4, 5])
>>> dill.temp.loadIO(dumpfile)
[1, 2, 3, 4, 5]
"""
import dill as pickle
if PY3:
from io import BytesIO as StringIO
else:
from StringIO import StringIO
value = getattr(buffer, 'getvalue', buffer) # value or buffer.getvalue
if value != buffer: value = value() # buffer.getvalue()
return pickle.load(StringIO(value))
def dumpIO(object, **kwds):
"""dill.dump of object to a buffer.
Loads with "dill.temp.loadIO". Returns the buffer object.
>>> dumpfile = dill.temp.dumpIO([1, 2, 3, 4, 5])
>>> dill.temp.loadIO(dumpfile)
[1, 2, 3, 4, 5]
"""
import dill as pickle
if PY3:
from io import BytesIO as StringIO
else:
from StringIO import StringIO
file = StringIO()
pickle.dump(object, file)
file.flush()
return file
def loadIO_source(buffer, **kwds):
"""load an object that was stored with dill.temp.dumpIO_source
buffer: buffer object
alias: string name of stored object
>>> f = lambda x:x**2
>>> pyfile = dill.temp.dumpIO_source(f, alias='_f')
>>> _f = dill.temp.loadIO_source(pyfile)
>>> _f(4)
16
"""
alias = kwds.pop('alias', None)
source = getattr(buffer, 'getvalue', buffer) # source or buffer.getvalue
if source != buffer: source = source() # buffer.getvalue()
if PY3: source = source.decode() # buffer to string
if not alias:
tag = source.strip().splitlines()[-1].split()
if tag[0] != '#NAME:':
stub = source.splitlines()[0]
raise IOError("unknown name for code: %s" % stub)
alias = tag[-1]
local = {}
exec(source, local)
_ = eval("%s" % alias, local)
return _
def dumpIO_source(object, **kwds):
"""write object source to a buffer (instead of dill.dump)
Loads by with dill.temp.loadIO_source. Returns the buffer object.
>>> f = lambda x:x**2
>>> pyfile = dill.temp.dumpIO_source(f, alias='_f')
>>> _f = dill.temp.loadIO_source(pyfile)
>>> _f(4)
16
Optional kwds:
If 'alias' is specified, the object will be renamed to the given string.
"""
from .source import importable, getname
if PY3:
from io import BytesIO as StringIO
else:
from StringIO import StringIO
alias = kwds.pop('alias', '') #XXX: include an alias so a name is known
name = str(alias) or getname(object)
name = "\n#NAME: %s\n" % name
#XXX: assumes kwds['dir'] is writable and on $PYTHONPATH
file = StringIO()
file.write(b(''.join([importable(object, alias=alias),name])))
file.flush()
return file
del contextlib
# EOF

@ -0,0 +1,23 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2018-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
"""
to run this test suite, first build and install `dill`.
$ python setup.py build
$ python setup.py install
then run the tests with:
$ python -m dill.tests
or, if `nose` is installed:
$ nosetests
"""

@ -0,0 +1,27 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2018-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
from __future__ import print_function
import glob
import os
try:
import pox
python = pox.which_python(version=True, fullpath=False) or 'python'
except ImportError:
python = 'python'
suite = os.path.dirname(__file__) or os.path.curdir
tests = glob.glob(suite + os.path.sep + 'test_*.py')
if __name__ == '__main__':
for test in tests:
print('.', end='')
os.system('{0} {1}'.format(python, test))
print('')

@ -0,0 +1,63 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
from dill import check
import sys
from dill.temp import capture
from dill._dill import PY3
#FIXME: this doesn't catch output... it's from the internal call
def raise_check(func, **kwds):
try:
with capture('stdout') as out:
check(func, **kwds)
except Exception:
e = sys.exc_info()[1]
raise AssertionError(str(e))
else:
assert 'Traceback' not in out.getvalue()
finally:
out.close()
f = lambda x:x**2
def test_simple():
raise_check(f)
def test_recurse():
raise_check(f, recurse=True)
def test_byref():
raise_check(f, byref=True)
def test_protocol():
raise_check(f, protocol=True)
def test_python():
raise_check(f, python=None)
#TODO: test incompatible versions
#TODO: test dump failure
#TODO: test load failure
if __name__ == '__main__':
test_simple()
test_recurse()
test_byref()
test_protocol()
test_python()

@ -0,0 +1,199 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
import dill
import sys
dill.settings['recurse'] = True
# test classdefs
class _class:
def _method(self):
pass
def ok(self):
return True
class _class2:
def __call__(self):
pass
def ok(self):
return True
class _newclass(object):
def _method(self):
pass
def ok(self):
return True
class _newclass2(object):
def __call__(self):
pass
def ok(self):
return True
class _meta(type):
pass
def __call__(self):
pass
def ok(self):
return True
_mclass = _meta("_mclass", (object,), {"__call__": __call__, "ok": ok})
del __call__
del ok
o = _class()
oc = _class2()
n = _newclass()
nc = _newclass2()
m = _mclass()
# test pickles for class instances
def test_class_instances():
assert dill.pickles(o)
assert dill.pickles(oc)
assert dill.pickles(n)
assert dill.pickles(nc)
assert dill.pickles(m)
def test_class_objects():
clslist = [_class,_class2,_newclass,_newclass2,_mclass]
objlist = [o,oc,n,nc,m]
_clslist = [dill.dumps(obj) for obj in clslist]
_objlist = [dill.dumps(obj) for obj in objlist]
for obj in clslist:
globals().pop(obj.__name__)
del clslist
for obj in ['o','oc','n','nc']:
globals().pop(obj)
del objlist
del obj
for obj,cls in zip(_objlist,_clslist):
_cls = dill.loads(cls)
_obj = dill.loads(obj)
assert _obj.ok()
assert _cls.ok(_cls())
if _cls.__name__ == "_mclass":
assert type(_cls).__name__ == "_meta"
# test NoneType
def test_none():
assert dill.pickles(type(None))
if hex(sys.hexversion) >= '0x20600f0':
from collections import namedtuple
Z = namedtuple("Z", ['a','b'])
Zi = Z(0,1)
X = namedtuple("Y", ['a','b'])
X.__name__ = "X"
if hex(sys.hexversion) >= '0x30300f0':
X.__qualname__ = "X" #XXX: name must 'match' or fails to pickle
Xi = X(0,1)
Bad = namedtuple("FakeName", ['a','b'])
Badi = Bad(0,1)
else:
Z = Zi = X = Xi = Bad = Badi = None
# test namedtuple
def test_namedtuple():
assert Z is dill.loads(dill.dumps(Z))
assert Zi == dill.loads(dill.dumps(Zi))
assert X is dill.loads(dill.dumps(X))
assert Xi == dill.loads(dill.dumps(Xi))
assert Bad is not dill.loads(dill.dumps(Bad))
assert Bad._fields == dill.loads(dill.dumps(Bad))._fields
assert tuple(Badi) == tuple(dill.loads(dill.dumps(Badi)))
def test_array_nested():
try:
import numpy as np
x = np.array([1])
y = (x,)
dill.dumps(x)
assert y == dill.loads(dill.dumps(y))
except ImportError: pass
def test_array_subclass():
try:
import numpy as np
class TestArray(np.ndarray):
def __new__(cls, input_array, color):
obj = np.asarray(input_array).view(cls)
obj.color = color
return obj
def __array_finalize__(self, obj):
if obj is None:
return
if isinstance(obj, type(self)):
self.color = obj.color
def __getnewargs__(self):
return np.asarray(self), self.color
a1 = TestArray(np.zeros(100), color='green')
assert dill.pickles(a1)
assert a1.__dict__ == dill.copy(a1).__dict__
a2 = a1[0:9]
assert dill.pickles(a2)
assert a2.__dict__ == dill.copy(a2).__dict__
class TestArray2(np.ndarray):
color = 'blue'
a3 = TestArray2([1,2,3,4,5])
a3.color = 'green'
assert dill.pickles(a3)
assert a3.__dict__ == dill.copy(a3).__dict__
except ImportError: pass
def test_method_decorator():
class A(object):
@classmethod
def test(cls):
pass
a = A()
res = dill.dumps(a)
new_obj = dill.loads(res)
new_obj.__class__.test()
# test slots
class Y(object):
__slots__ = ['y']
def __init__(self, y):
self.y = y
value = 123
y = Y(value)
def test_slots():
assert dill.pickles(Y)
assert dill.pickles(y)
assert dill.pickles(Y.y)
assert dill.copy(y).y == value
if __name__ == '__main__':
test_class_instances()
test_class_objects()
test_none()
test_namedtuple()
test_array_nested()
test_array_subclass()
test_method_decorator()
test_slots()

@ -0,0 +1,156 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
from dill.detect import baditems, badobjects, badtypes, errors, parent, at, globalvars
from dill import settings
from dill._dill import IS_PYPY
from pickle import PicklingError
import inspect
def test_bad_things():
f = inspect.currentframe()
assert baditems(f) == [f]
#assert baditems(globals()) == [f] #XXX
assert badobjects(f) is f
assert badtypes(f) == type(f)
assert type(errors(f)) is PicklingError if IS_PYPY else TypeError
d = badtypes(f, 1)
assert isinstance(d, dict)
assert list(badobjects(f, 1).keys()) == list(d.keys())
assert list(errors(f, 1).keys()) == list(d.keys())
s = set([(err.__class__.__name__,err.args[0]) for err in list(errors(f, 1).values())])
a = dict(s)
assert len(s) is len(a) # TypeError (and possibly PicklingError)
n = 1 if IS_PYPY else 2
assert len(a) is n if 'PicklingError' in a.keys() else n-1
def test_parent():
x = [4,5,6,7]
listiter = iter(x)
obj = parent(listiter, list)
assert obj is x
if IS_PYPY: assert parent(obj, int) is None
else: assert parent(obj, int) is x[-1] # python oddly? finds last int
assert at(id(at)) is at
a, b, c = 1, 2, 3
def squared(x):
return a+x**2
def foo(x):
def bar(y):
return squared(x)+y
return bar
class _class:
def _method(self):
pass
def ok(self):
return True
def test_globals():
def f():
a
def g():
b
def h():
c
assert globalvars(f) == dict(a=1, b=2, c=3)
res = globalvars(foo, recurse=True)
assert set(res) == set(['squared', 'a'])
res = globalvars(foo, recurse=False)
assert res == {}
zap = foo(2)
res = globalvars(zap, recurse=True)
assert set(res) == set(['squared', 'a'])
res = globalvars(zap, recurse=False)
assert set(res) == set(['squared'])
del zap
res = globalvars(squared)
assert set(res) == set(['a'])
# FIXME: should find referenced __builtins__
#res = globalvars(_class, recurse=True)
#assert set(res) == set(['True'])
#res = globalvars(_class, recurse=False)
#assert res == {}
#res = globalvars(_class.ok, recurse=True)
#assert set(res) == set(['True'])
#res = globalvars(_class.ok, recurse=False)
#assert set(res) == set(['True'])
#98 dill ignores __getstate__ in interactive lambdas
bar = [0]
class Foo(object):
def __init__(self):
pass
def __getstate__(self):
bar[0] = bar[0]+1
return {}
def __setstate__(self, data):
pass
f = Foo()
def test_getstate():
from dill import dumps, loads
dumps(f)
b = bar[0]
dumps(lambda: f, recurse=False) # doesn't call __getstate__
assert bar[0] == b
dumps(lambda: f, recurse=True) # calls __getstate__
assert bar[0] == b + 1
#97 serialize lambdas in test files
def test_deleted():
from dill import dumps, loads
from math import sin, pi
global sin
def sinc(x):
return sin(x)/x
settings['recurse'] = True
_sinc = dumps(sinc)
sin = globals().pop('sin')
sin = 1
del sin
sinc_ = loads(_sinc) # no NameError... pickling preserves 'sin'
res = sinc_(1)
from math import sin
assert sinc(1) == res
def test_lambdify():
try:
from sympy import symbols, lambdify
except ImportError:
return
settings['recurse'] = True
x = symbols("x")
y = x**2
f = lambdify([x], y)
z = min
d = globals()
globalvars(f, recurse=True, builtin=True)
assert z is min
assert d is globals()
if __name__ == '__main__':
test_bad_things()
test_parent()
test_globals()
test_getstate()
test_deleted()
test_lambdify()

@ -0,0 +1,110 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
from dill import __diff as diff
import sys
IS_PYPY = not hasattr(sys, 'getrefcount')
class A:
pass
def test_diff():
a = A()
b = A()
c = A()
a.a = b
b.a = c
diff.memorise(a)
assert not diff.has_changed(a)
c.a = 1
assert diff.has_changed(a)
diff.memorise(c, force=True)
assert not diff.has_changed(a)
c.a = 2
assert diff.has_changed(a)
changed = diff.whats_changed(a)
assert list(changed[0].keys()) == ["a"]
assert not changed[1]
a2 = []
b2 = [a2]
c2 = [b2]
diff.memorise(c2)
assert not diff.has_changed(c2)
a2.append(1)
assert diff.has_changed(c2)
changed = diff.whats_changed(c2)
assert changed[0] == {}
assert changed[1]
a3 = {}
b3 = {1: a3}
c3 = {1: b3}
diff.memorise(c3)
assert not diff.has_changed(c3)
a3[1] = 1
assert diff.has_changed(c3)
changed = diff.whats_changed(c3)
assert changed[0] == {}
assert changed[1]
if not IS_PYPY:
try:
import abc
# make sure the "_abc_invaldation_counter" doesn't make test fail
diff.memorise(abc.ABCMeta, force=True)
assert not diff.has_changed(abc)
abc.ABCMeta.zzz = 1
assert diff.has_changed(abc)
changed = diff.whats_changed(abc)
assert list(changed[0].keys()) == ["ABCMeta"]
assert not changed[1]
except ImportError:
pass
'''
import Queue
diff.memorise(Queue, force=True)
assert not diff.has_changed(Queue)
Queue.Queue.zzz = 1
assert diff.has_changed(Queue)
changed = diff.whats_changed(Queue)
assert list(changed[0].keys()) == ["Queue"]
assert not changed[1]
import math
diff.memorise(math, force=True)
assert not diff.has_changed(math)
math.zzz = 1
assert diff.has_changed(math)
changed = diff.whats_changed(math)
assert list(changed[0].keys()) == ["zzz"]
assert not changed[1]
'''
a = A()
b = A()
c = A()
a.a = b
b.a = c
diff.memorise(a)
assert not diff.has_changed(a)
c.a = 1
assert diff.has_changed(a)
diff.memorise(c, force=True)
assert not diff.has_changed(a)
del c.a
assert diff.has_changed(a)
changed = diff.whats_changed(a)
assert list(changed[0].keys()) == ["a"]
assert not changed[1]
if __name__ == '__main__':
test_diff()

@ -0,0 +1,38 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
import dill as pickle
try:
from StringIO import StringIO
except ImportError:
from io import BytesIO as StringIO
def my_fn(x):
return x * 17
def test_extend():
obj = lambda : my_fn(34)
assert obj() == 578
obj_io = StringIO()
pickler = pickle.Pickler(obj_io)
pickler.dump(obj)
obj_str = obj_io.getvalue()
obj2_io = StringIO(obj_str)
unpickler = pickle.Unpickler(obj2_io)
obj2 = unpickler.load()
assert obj2() == 578
if __name__ == '__main__':
test_extend()

@ -0,0 +1,502 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
import os
import sys
import string
import random
import dill
dill.settings['recurse'] = True
fname = "_test_file.txt"
rand_chars = list(string.ascii_letters) + ["\n"] * 40 # bias newline
if sys.hexversion < 0x03030000:
FileNotFoundError = IOError
buffer_error = ValueError("invalid buffer size")
dne_error = FileNotFoundError("[Errno 2] No such file or directory: '%s'" % fname)
def write_randomness(number=200):
f = open(fname, "w")
for i in range(number):
f.write(random.choice(rand_chars))
f.close()
f = open(fname, "r")
contents = f.read()
f.close()
return contents
def trunc_file():
open(fname, "w").close()
def throws(op, args, exc):
try:
op(*args)
except type(exc):
return sys.exc_info()[1].args == exc.args
else:
return False
def teardown_module():
if os.path.exists(fname):
os.remove(fname)
def bench(strictio, fmode, skippypy):
import platform
if skippypy and platform.python_implementation() == 'PyPy':
# Skip for PyPy...
return
# file exists, with same contents
# read
write_randomness()
f = open(fname, "r")
_f = dill.loads(dill.dumps(f, fmode=fmode))#, strictio=strictio))
assert _f.mode == f.mode
assert _f.tell() == f.tell()
assert _f.read() == f.read()
f.close()
_f.close()
# write
f = open(fname, "w")
f.write("hello")
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
f1mode = f.mode
ftell = f.tell()
f.close()
f2 = dill.loads(f_dumped) #FIXME: fails due to pypy/issues/1233
# TypeError: expected py_object instance instead of str
f2mode = f2.mode
f2tell = f2.tell()
f2name = f2.name
f2.write(" world!")
f2.close()
if fmode == dill.HANDLE_FMODE:
assert open(fname).read() == " world!"
assert f2mode == f1mode
assert f2tell == 0
elif fmode == dill.CONTENTS_FMODE:
assert open(fname).read() == "hello world!"
assert f2mode == f1mode
assert f2tell == ftell
assert f2name == fname
elif fmode == dill.FILE_FMODE:
assert open(fname).read() == "hello world!"
assert f2mode == f1mode
assert f2tell == ftell
else:
raise RuntimeError("Unknown file mode '%s'" % fmode)
# append
trunc_file()
f = open(fname, "a")
f.write("hello")
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
f1mode = f.mode
ftell = f.tell()
f.close()
f2 = dill.loads(f_dumped)
f2mode = f2.mode
f2tell = f2.tell()
f2.write(" world!")
f2.close()
assert f2mode == f1mode
if fmode == dill.CONTENTS_FMODE:
assert open(fname).read() == "hello world!"
assert f2tell == ftell
elif fmode == dill.HANDLE_FMODE:
assert open(fname).read() == "hello world!"
assert f2tell == ftell
elif fmode == dill.FILE_FMODE:
assert open(fname).read() == "hello world!"
assert f2tell == ftell
else:
raise RuntimeError("Unknown file mode '%s'" % fmode)
# file exists, with different contents (smaller size)
# read
write_randomness()
f = open(fname, "r")
fstr = f.read()
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
f1mode = f.mode
ftell = f.tell()
f.close()
_flen = 150
_fstr = write_randomness(number=_flen)
if strictio: # throw error if ftell > EOF
assert throws(dill.loads, (f_dumped,), buffer_error)
else:
f2 = dill.loads(f_dumped)
assert f2.mode == f1mode
if fmode == dill.CONTENTS_FMODE:
assert f2.tell() == _flen
assert f2.read() == ""
f2.seek(0)
assert f2.read() == _fstr
assert f2.tell() == _flen # 150
elif fmode == dill.HANDLE_FMODE:
assert f2.tell() == 0
assert f2.read() == _fstr
assert f2.tell() == _flen # 150
elif fmode == dill.FILE_FMODE:
assert f2.tell() == ftell # 200
assert f2.read() == ""
f2.seek(0)
assert f2.read() == fstr
assert f2.tell() == ftell # 200
else:
raise RuntimeError("Unknown file mode '%s'" % fmode)
f2.close()
# write
write_randomness()
f = open(fname, "w")
f.write("hello")
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
f1mode = f.mode
ftell = f.tell()
f.close()
fstr = open(fname).read()
f = open(fname, "w")
f.write("h")
_ftell = f.tell()
f.close()
if strictio: # throw error if ftell > EOF
assert throws(dill.loads, (f_dumped,), buffer_error)
else:
f2 = dill.loads(f_dumped)
f2mode = f2.mode
f2tell = f2.tell()
f2.write(" world!")
f2.close()
if fmode == dill.CONTENTS_FMODE:
assert open(fname).read() == "h world!"
assert f2mode == f1mode
assert f2tell == _ftell
elif fmode == dill.HANDLE_FMODE:
assert open(fname).read() == " world!"
assert f2mode == f1mode
assert f2tell == 0
elif fmode == dill.FILE_FMODE:
assert open(fname).read() == "hello world!"
assert f2mode == f1mode
assert f2tell == ftell
else:
raise RuntimeError("Unknown file mode '%s'" % fmode)
f2.close()
# append
trunc_file()
f = open(fname, "a")
f.write("hello")
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
f1mode = f.mode
ftell = f.tell()
f.close()
fstr = open(fname).read()
f = open(fname, "w")
f.write("h")
_ftell = f.tell()
f.close()
if strictio: # throw error if ftell > EOF
assert throws(dill.loads, (f_dumped,), buffer_error)
else:
f2 = dill.loads(f_dumped)
f2mode = f2.mode
f2tell = f2.tell()
f2.write(" world!")
f2.close()
assert f2mode == f1mode
if fmode == dill.CONTENTS_FMODE:
# position of writes cannot be changed on some OSs
assert open(fname).read() == "h world!"
assert f2tell == _ftell
elif fmode == dill.HANDLE_FMODE:
assert open(fname).read() == "h world!"
assert f2tell == _ftell
elif fmode == dill.FILE_FMODE:
assert open(fname).read() == "hello world!"
assert f2tell == ftell
else:
raise RuntimeError("Unknown file mode '%s'" % fmode)
f2.close()
# file does not exist
# read
write_randomness()
f = open(fname, "r")
fstr = f.read()
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
f1mode = f.mode
ftell = f.tell()
f.close()
os.remove(fname)
if strictio: # throw error if file DNE
assert throws(dill.loads, (f_dumped,), dne_error)
else:
f2 = dill.loads(f_dumped)
assert f2.mode == f1mode
if fmode == dill.CONTENTS_FMODE:
# FIXME: this fails on systems where f2.tell() always returns 0
# assert f2.tell() == ftell # 200
assert f2.read() == ""
f2.seek(0)
assert f2.read() == ""
assert f2.tell() == 0
elif fmode == dill.FILE_FMODE:
assert f2.tell() == ftell # 200
assert f2.read() == ""
f2.seek(0)
assert f2.read() == fstr
assert f2.tell() == ftell # 200
elif fmode == dill.HANDLE_FMODE:
assert f2.tell() == 0
assert f2.read() == ""
assert f2.tell() == 0
else:
raise RuntimeError("Unknown file mode '%s'" % fmode)
f2.close()
# write
write_randomness()
f = open(fname, "w+")
f.write("hello")
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
ftell = f.tell()
f1mode = f.mode
f.close()
os.remove(fname)
if strictio: # throw error if file DNE
assert throws(dill.loads, (f_dumped,), dne_error)
else:
f2 = dill.loads(f_dumped)
f2mode = f2.mode
f2tell = f2.tell()
f2.write(" world!")
f2.close()
if fmode == dill.CONTENTS_FMODE:
assert open(fname).read() == " world!"
assert f2mode == 'w+'
assert f2tell == 0
elif fmode == dill.HANDLE_FMODE:
assert open(fname).read() == " world!"
assert f2mode == f1mode
assert f2tell == 0
elif fmode == dill.FILE_FMODE:
assert open(fname).read() == "hello world!"
assert f2mode == f1mode
assert f2tell == ftell
else:
raise RuntimeError("Unknown file mode '%s'" % fmode)
# append
trunc_file()
f = open(fname, "a")
f.write("hello")
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
ftell = f.tell()
f1mode = f.mode
f.close()
os.remove(fname)
if strictio: # throw error if file DNE
assert throws(dill.loads, (f_dumped,), dne_error)
else:
f2 = dill.loads(f_dumped)
f2mode = f2.mode
f2tell = f2.tell()
f2.write(" world!")
f2.close()
assert f2mode == f1mode
if fmode == dill.CONTENTS_FMODE:
assert open(fname).read() == " world!"
assert f2tell == 0
elif fmode == dill.HANDLE_FMODE:
assert open(fname).read() == " world!"
assert f2tell == 0
elif fmode == dill.FILE_FMODE:
assert open(fname).read() == "hello world!"
assert f2tell == ftell
else:
raise RuntimeError("Unknown file mode '%s'" % fmode)
# file exists, with different contents (larger size)
# read
write_randomness()
f = open(fname, "r")
fstr = f.read()
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
f1mode = f.mode
ftell = f.tell()
f.close()
_flen = 250
_fstr = write_randomness(number=_flen)
# XXX: no safe_file: no way to be 'safe'?
f2 = dill.loads(f_dumped)
assert f2.mode == f1mode
if fmode == dill.CONTENTS_FMODE:
assert f2.tell() == ftell # 200
assert f2.read() == _fstr[ftell:]
f2.seek(0)
assert f2.read() == _fstr
assert f2.tell() == _flen # 250
elif fmode == dill.HANDLE_FMODE:
assert f2.tell() == 0
assert f2.read() == _fstr
assert f2.tell() == _flen # 250
elif fmode == dill.FILE_FMODE:
assert f2.tell() == ftell # 200
assert f2.read() == ""
f2.seek(0)
assert f2.read() == fstr
assert f2.tell() == ftell # 200
else:
raise RuntimeError("Unknown file mode '%s'" % fmode)
f2.close() # XXX: other alternatives?
# write
f = open(fname, "w")
f.write("hello")
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
f1mode = f.mode
ftell = f.tell()
fstr = open(fname).read()
f.write(" and goodbye!")
_ftell = f.tell()
f.close()
# XXX: no safe_file: no way to be 'safe'?
f2 = dill.loads(f_dumped)
f2mode = f2.mode
f2tell = f2.tell()
f2.write(" world!")
f2.close()
if fmode == dill.CONTENTS_FMODE:
assert open(fname).read() == "hello world!odbye!"
assert f2mode == f1mode
assert f2tell == ftell
elif fmode == dill.HANDLE_FMODE:
assert open(fname).read() == " world!"
assert f2mode == f1mode
assert f2tell == 0
elif fmode == dill.FILE_FMODE:
assert open(fname).read() == "hello world!"
assert f2mode == f1mode
assert f2tell == ftell
else:
raise RuntimeError("Unknown file mode '%s'" % fmode)
f2.close()
# append
trunc_file()
f = open(fname, "a")
f.write("hello")
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
f1mode = f.mode
ftell = f.tell()
fstr = open(fname).read()
f.write(" and goodbye!")
_ftell = f.tell()
f.close()
# XXX: no safe_file: no way to be 'safe'?
f2 = dill.loads(f_dumped)
f2mode = f2.mode
f2tell = f2.tell()
f2.write(" world!")
f2.close()
assert f2mode == f1mode
if fmode == dill.CONTENTS_FMODE:
assert open(fname).read() == "hello and goodbye! world!"
assert f2tell == ftell
elif fmode == dill.HANDLE_FMODE:
assert open(fname).read() == "hello and goodbye! world!"
assert f2tell == _ftell
elif fmode == dill.FILE_FMODE:
assert open(fname).read() == "hello world!"
assert f2tell == ftell
else:
raise RuntimeError("Unknown file mode '%s'" % fmode)
f2.close()
def test_nostrictio_handlefmode():
bench(False, dill.HANDLE_FMODE, False)
teardown_module()
def test_nostrictio_filefmode():
bench(False, dill.FILE_FMODE, False)
teardown_module()
def test_nostrictio_contentsfmode():
bench(False, dill.CONTENTS_FMODE, True)
teardown_module()
#bench(True, dill.HANDLE_FMODE, False)
#bench(True, dill.FILE_FMODE, False)
#bench(True, dill.CONTENTS_FMODE, True)
if __name__ == '__main__':
test_nostrictio_handlefmode()
test_nostrictio_filefmode()
test_nostrictio_contentsfmode()

@ -0,0 +1,63 @@
#!/usr/bin/env python
import dill
import sys
dill.settings['recurse'] = True
def is_py3():
return hex(sys.hexversion) >= '0x30000f0'
def function_a(a):
return a
def function_b(b, b1):
return b + b1
def function_c(c, c1=1):
return c + c1
def function_d(d, d1, d2=1):
return d + d1 + d2
if is_py3():
exec('''
def function_e(e, *e1, e2=1, e3=2):
return e + sum(e1) + e2 + e3''')
def test_functions():
dumped_func_a = dill.dumps(function_a)
assert dill.loads(dumped_func_a)(0) == 0
dumped_func_b = dill.dumps(function_b)
assert dill.loads(dumped_func_b)(1,2) == 3
dumped_func_c = dill.dumps(function_c)
assert dill.loads(dumped_func_c)(1) == 2
assert dill.loads(dumped_func_c)(1, 2) == 3
dumped_func_d = dill.dumps(function_d)
assert dill.loads(dumped_func_d)(1, 2) == 4
assert dill.loads(dumped_func_d)(1, 2, 3) == 6
assert dill.loads(dumped_func_d)(1, 2, d2=3) == 6
if is_py3():
exec('''
dumped_func_e = dill.dumps(function_e)
assert dill.loads(dumped_func_e)(1, 2) == 6
assert dill.loads(dumped_func_e)(1, 2, 3) == 9
assert dill.loads(dumped_func_e)(1, 2, e2=3) == 8
assert dill.loads(dumped_func_e)(1, 2, e2=3, e3=4) == 10
assert dill.loads(dumped_func_e)(1, 2, 3, e2=4) == 12
assert dill.loads(dumped_func_e)(1, 2, 3, e2=4, e3=5) == 15''')
if __name__ == '__main__':
test_functions()

@ -0,0 +1,39 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
import functools
import dill
dill.settings['recurse'] = True
def f(a, b, c): # without keywords
pass
def g(a, b, c=2): # with keywords
pass
def h(a=1, b=2, c=3): # without args
pass
def test_functools():
fp = functools.partial(f, 1, 2)
gp = functools.partial(g, 1, c=2)
hp = functools.partial(h, 1, c=2)
bp = functools.partial(int, base=2)
assert dill.pickles(fp, safe=True)
assert dill.pickles(gp, safe=True)
assert dill.pickles(hp, safe=True)
assert dill.pickles(bp, safe=True)
if __name__ == '__main__':
test_functools()

@ -0,0 +1,121 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
import dill
dill.settings['recurse'] = True
def wtf(x,y,z):
def zzz():
return x
def yyy():
return y
def xxx():
return z
return zzz,yyy
def quad(a=1, b=1, c=0):
inverted = [False]
def invert():
inverted[0] = not inverted[0]
def dec(f):
def func(*args, **kwds):
x = f(*args, **kwds)
if inverted[0]: x = -x
return a*x**2 + b*x + c
func.__wrapped__ = f
func.invert = invert
func.inverted = inverted
return func
return dec
@quad(a=0,b=2)
def double_add(*args):
return sum(args)
fx = sum([1,2,3])
### to make it interesting...
def quad_factory(a=1,b=1,c=0):
def dec(f):
def func(*args,**kwds):
fx = f(*args,**kwds)
return a*fx**2 + b*fx + c
return func
return dec
@quad_factory(a=0,b=4,c=0)
def quadish(x):
return x+1
quadratic = quad_factory()
def doubler(f):
def inner(*args, **kwds):
fx = f(*args, **kwds)
return 2*fx
return inner
@doubler
def quadruple(x):
return 2*x
def test_mixins():
# test mixins
assert double_add(1,2,3) == 2*fx
double_add.invert()
assert double_add(1,2,3) == -2*fx
_d = dill.copy(double_add)
assert _d(1,2,3) == -2*fx
#_d.invert() #FIXME: fails seemingly randomly
#assert _d(1,2,3) == 2*fx
assert _d.__wrapped__(1,2,3) == fx
# XXX: issue or feature? in python3.4, inverted is linked through copy
if not double_add.inverted[0]:
double_add.invert()
# test some stuff from source and pointers
ds = dill.source
dd = dill.detect
assert ds.getsource(dd.freevars(quadish)['f']) == '@quad_factory(a=0,b=4,c=0)\ndef quadish(x):\n return x+1\n'
assert ds.getsource(dd.freevars(quadruple)['f']) == '@doubler\ndef quadruple(x):\n return 2*x\n'
assert ds.importable(quadish, source=False) == 'from %s import quadish\n' % __name__
assert ds.importable(quadruple, source=False) == 'from %s import quadruple\n' % __name__
assert ds.importable(quadratic, source=False) == 'from %s import quadratic\n' % __name__
assert ds.importable(double_add, source=False) == 'from %s import double_add\n' % __name__
assert ds.importable(quadruple, source=True) == 'def doubler(f):\n def inner(*args, **kwds):\n fx = f(*args, **kwds)\n return 2*fx\n return inner\n\n@doubler\ndef quadruple(x):\n return 2*x\n'
#***** #FIXME: this needs work
result = ds.importable(quadish, source=True)
a,b,c,_,result = result.split('\n',4)
assert result == 'def quad_factory(a=1,b=1,c=0):\n def dec(f):\n def func(*args,**kwds):\n fx = f(*args,**kwds)\n return a*fx**2 + b*fx + c\n return func\n return dec\n\n@quad_factory(a=0,b=4,c=0)\ndef quadish(x):\n return x+1\n'
assert set([a,b,c]) == set(['a = 0', 'c = 0', 'b = 4'])
result = ds.importable(quadratic, source=True)
a,b,c,result = result.split('\n',3)
assert result == '\ndef dec(f):\n def func(*args,**kwds):\n fx = f(*args,**kwds)\n return a*fx**2 + b*fx + c\n return func\n'
assert set([a,b,c]) == set(['a = 1', 'c = 0', 'b = 1'])
result = ds.importable(double_add, source=True)
a,b,c,d,_,result = result.split('\n',5)
assert result == 'def quad(a=1, b=1, c=0):\n inverted = [False]\n def invert():\n inverted[0] = not inverted[0]\n def dec(f):\n def func(*args, **kwds):\n x = f(*args, **kwds)\n if inverted[0]: x = -x\n return a*x**2 + b*x + c\n func.__wrapped__ = f\n func.invert = invert\n func.inverted = inverted\n return func\n return dec\n\n@quad(a=0,b=2)\ndef double_add(*args):\n return sum(args)\n'
assert set([a,b,c,d]) == set(['a = 0', 'c = 0', 'b = 2', 'inverted = [True]'])
#*****
if __name__ == '__main__':
test_mixins()

@ -0,0 +1,85 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
import sys
import dill
import test_mixins as module
try: from imp import reload
except ImportError: pass
dill.settings['recurse'] = True
cached = (module.__cached__ if hasattr(module, "__cached__")
else module.__file__.split(".", 1)[0] + ".pyc")
module.a = 1234
pik_mod = dill.dumps(module)
module.a = 0
# remove module
del sys.modules[module.__name__]
del module
module = dill.loads(pik_mod)
def test_attributes():
#assert hasattr(module, "a") and module.a == 1234 #FIXME: -m dill.tests
assert module.double_add(1, 2, 3) == 2 * module.fx
# Restart, and test use_diff
reload(module)
try:
dill.use_diff()
module.a = 1234
pik_mod = dill.dumps(module)
module.a = 0
# remove module
del sys.modules[module.__name__]
del module
module = dill.loads(pik_mod)
def test_diff_attributes():
assert hasattr(module, "a") and module.a == 1234
assert module.double_add(1, 2, 3) == 2 * module.fx
except AttributeError:
def test_diff_attributes():
pass
# clean up
import os
if os.path.exists(cached):
os.remove(cached)
pycache = os.path.join(os.path.dirname(module.__file__), "__pycache__")
if os.path.exists(pycache) and not os.listdir(pycache):
os.removedirs(pycache)
# test when module is None
import math
def get_lambda(str, **kwarg):
return eval(str, kwarg, None)
obj = get_lambda('lambda x: math.exp(x)', math=math)
def test_module_is_none():
assert obj.__module__ is None
assert dill.copy(obj)(3) == obj(3)
if __name__ == '__main__':
test_attributes()
test_diff_attributes()
test_module_is_none()

@ -0,0 +1,54 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
import dill
dill.settings['recurse'] = True
def f(func):
def w(*args):
return f(*args)
return w
@f
def f2(): pass
# check when __main__ and on import
def test_decorated():
assert dill.pickles(f2)
import doctest
import logging
logging.basicConfig(level=logging.DEBUG)
class SomeUnreferencedUnpicklableClass(object):
def __reduce__(self):
raise Exception
unpicklable = SomeUnreferencedUnpicklableClass()
# This works fine outside of Doctest:
def test_normal():
serialized = dill.dumps(lambda x: x)
# should not try to pickle unpicklable object in __globals__
def tests():
"""
>>> serialized = dill.dumps(lambda x: x)
"""
return
#print("\n\nRunning Doctest:")
def test_doctest():
doctest.testmod()
if __name__ == '__main__':
test_decorated()
test_normal()
test_doctest()

@ -0,0 +1,135 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
"""
test dill's ability to handle nested functions
"""
import os
import math
import dill as pickle
pickle.settings['recurse'] = True
# the nested function: pickle should fail here, but dill is ok.
def adder(augend):
zero = [0]
def inner(addend):
return addend + augend + zero[0]
return inner
# rewrite the nested function using a class: standard pickle should work here.
class cadder(object):
def __init__(self, augend):
self.augend = augend
self.zero = [0]
def __call__(self, addend):
return addend + self.augend + self.zero[0]
# rewrite again, but as an old-style class
class c2adder:
def __init__(self, augend):
self.augend = augend
self.zero = [0]
def __call__(self, addend):
return addend + self.augend + self.zero[0]
# some basic class stuff
class basic(object):
pass
class basic2:
pass
x = 5
y = 1
def test_basic():
a = [0, 1, 2]
pa = pickle.dumps(a)
pmath = pickle.dumps(math) #XXX: FAILS in pickle
pmap = pickle.dumps(map)
# ...
la = pickle.loads(pa)
lmath = pickle.loads(pmath)
lmap = pickle.loads(pmap)
assert list(map(math.sin, a)) == list(lmap(lmath.sin, la))
def test_basic_class():
pbasic2 = pickle.dumps(basic2)
_pbasic2 = pickle.loads(pbasic2)()
pbasic = pickle.dumps(basic)
_pbasic = pickle.loads(pbasic)()
def test_c2adder():
pc2adder = pickle.dumps(c2adder)
pc2add5 = pickle.loads(pc2adder)(x)
assert pc2add5(y) == x+y
def test_pickled_cadder():
pcadder = pickle.dumps(cadder)
pcadd5 = pickle.loads(pcadder)(x)
assert pcadd5(y) == x+y
def test_raw_adder_and_inner():
add5 = adder(x)
assert add5(y) == x+y
def test_pickled_adder():
padder = pickle.dumps(adder)
padd5 = pickle.loads(padder)(x)
assert padd5(y) == x+y
def test_pickled_inner():
add5 = adder(x)
pinner = pickle.dumps(add5) #XXX: FAILS in pickle
p5add = pickle.loads(pinner)
assert p5add(y) == x+y
def test_moduledict_where_not_main():
try:
from . import test_moduledict
except:
import test_moduledict
name = 'test_moduledict.py'
if os.path.exists(name) and os.path.exists(name+'c'):
os.remove(name+'c')
if os.path.exists(name) and hasattr(test_moduledict, "__cached__") \
and os.path.exists(test_moduledict.__cached__):
os.remove(getattr(test_moduledict, "__cached__"))
if os.path.exists("__pycache__") and not os.listdir("__pycache__"):
os.removedirs("__pycache__")
if __name__ == '__main__':
test_basic()
test_basic_class()
test_c2adder()
test_pickled_cadder()
test_raw_adder_and_inner()
test_pickled_adder()
test_pickled_inner()
test_moduledict_where_not_main()

@ -0,0 +1,62 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
"""
demonstrate dill's ability to pickle different python types
test pickling of all Python Standard Library objects (currently: CH 1-14 @ 2.7)
"""
import dill as pickle
pickle.settings['recurse'] = True
#pickle.detect.trace(True)
#import pickle
# get all objects for testing
from dill import load_types, objects, extend
load_types(pickleable=True,unpickleable=False)
# uncomment the next two lines to test cloudpickle
#extend(False)
#import cloudpickle as pickle
# helper objects
class _class:
def _method(self):
pass
# objects that *fail* if imported
special = {}
special['LambdaType'] = _lambda = lambda x: lambda y: x
special['MethodType'] = _method = _class()._method
special['UnboundMethodType'] = _class._method
objects.update(special)
def pickles(name, exact=False):
"""quick check if object pickles with dill"""
obj = objects[name]
try:
pik = pickle.loads(pickle.dumps(obj))
if exact:
try:
assert pik == obj
except AssertionError:
assert type(obj) == type(pik)
print ("weak: %s %s" % (name, type(obj)))
else:
assert type(obj) == type(pik)
except Exception:
print ("fails: %s %s" % (name, type(obj)))
def test_objects():
for member in objects.keys():
#pickles(member, exact=True)
pickles(member, exact=False)
if __name__ == '__main__':
test_objects()

@ -0,0 +1,62 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
import sys
import dill
dill.settings['recurse'] = True
class Foo(object):
def __init__(self):
self._data = 1
def _get_data(self):
return self._data
def _set_data(self, x):
self._data = x
data = property(_get_data, _set_data)
def test_data_not_none():
FooS = dill.copy(Foo)
assert FooS.data.fget is not None
assert FooS.data.fset is not None
assert FooS.data.fdel is None
def test_data_unchanged():
FooS = dill.copy(Foo)
try:
res = FooS().data
except Exception:
e = sys.exc_info()[1]
raise AssertionError(str(e))
else:
assert res == 1
def test_data_changed():
FooS = dill.copy(Foo)
try:
f = FooS()
f.data = 1024
res = f.data
except Exception:
e = sys.exc_info()[1]
raise AssertionError(str(e))
else:
assert res == 1024
if __name__ == '__main__':
test_data_not_none()
test_data_unchanged()
test_data_changed()

@ -0,0 +1,85 @@
import dill
from functools import partial
from dill._dill import PY3, OLDER
_super = super
class obj1(object):
def __init__(self):
super(obj1, self).__init__()
class obj2(object):
def __init__(self):
_super(obj2, self).__init__()
class obj3(object):
super_ = super
def __init__(self):
obj3.super_(obj3, self).__init__()
def test_super():
assert dill.copy(obj1(), byref=True)
assert dill.copy(obj1(), byref=True, recurse=True)
#assert dill.copy(obj1(), recurse=True) #FIXME: fails __main__.py
assert dill.copy(obj1())
assert dill.copy(obj2(), byref=True)
assert dill.copy(obj2(), byref=True, recurse=True)
#assert dill.copy(obj2(), recurse=True) #FIXME: fails __main__.py
assert dill.copy(obj2())
assert dill.copy(obj3(), byref=True)
assert dill.copy(obj3(), byref=True, recurse=True)
#assert dill.copy(obj3(), recurse=True) #FIXME: fails __main__.py
assert dill.copy(obj3())
def get_trigger(model):
pass
class Machine(object):
def __init__(self):
self.child = Model()
self.trigger = partial(get_trigger, self)
self.child.trigger = partial(get_trigger, self.child)
class Model(object):
pass
def test_partial():
assert dill.copy(Machine(), byref=True)
assert dill.copy(Machine(), byref=True, recurse=True)
if not OLDER:
assert dill.copy(Machine(), recurse=True)
assert dill.copy(Machine())
class Machine2(object):
def __init__(self):
self.go = partial(self.member, self)
def member(self, model):
pass
class SubMachine(Machine2):
def __init__(self):
_super(SubMachine, self).__init__()
#super(SubMachine, self).__init__() #XXX: works, except for 3.1-3.3
def test_partials():
assert dill.copy(SubMachine(), byref=True)
assert dill.copy(SubMachine(), byref=True, recurse=True)
#if not OLDER: #FIXME: fails __main__.py
# assert dill.copy(SubMachine(), recurse=True)
assert dill.copy(SubMachine())
if __name__ == '__main__':
#print(('byref','_super','_recurse','_memo','_stop','OLDER'))
test_super()
test_partial()
test_partials()

@ -0,0 +1,27 @@
#!/usr/bin/env python
#
# Author: Kirill Makhonin (@kirillmakhonin)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
import dill
class RestrictedType:
def __bool__(*args, **kwargs):
raise Exception('Restricted function')
__eq__ = __lt__ = __le__ = __ne__ = __gt__ = __ge__ = __hash__ = __bool__
glob_obj = RestrictedType()
def restricted_func():
a = glob_obj
def test_function_with_restricted_object():
deserialized = dill.loads(dill.dumps(restricted_func, recurse=True))
if __name__ == '__main__':
test_function_with_restricted_object()

@ -0,0 +1,99 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
"""
testing some selected object types
"""
import dill
dill.settings['recurse'] = True
verbose = False
def test_dict_contents():
c = type.__dict__
for i,j in c.items():
#try:
ok = dill.pickles(j)
#except:
# print ("FAIL: %s with %s" % (i, dill.detect.errors(j)))
if verbose: print ("%s: %s, %s" % (ok, type(j), j))
assert ok
if verbose: print ("")
def _g(x): yield x;
def _f():
try: raise
except:
from sys import exc_info
e, er, tb = exc_info()
return er, tb
class _d(object):
def _method(self):
pass
from dill import objects
from dill import load_types
load_types(pickleable=True,unpickleable=False)
_newclass = objects['ClassObjectType']
del objects
# getset_descriptor for new-style classes (fails on '_method', if not __main__)
def test_class_descriptors():
d = _d.__dict__
for i in d.values():
ok = dill.pickles(i)
if verbose: print ("%s: %s, %s" % (ok, type(i), i))
assert ok
if verbose: print ("")
od = _newclass.__dict__
for i in od.values():
ok = dill.pickles(i)
if verbose: print ("%s: %s, %s" % (ok, type(i), i))
assert ok
if verbose: print ("")
# (__main__) class instance for new-style classes
def test_class():
o = _d()
oo = _newclass()
ok = dill.pickles(o)
if verbose: print ("%s: %s, %s" % (ok, type(o), o))
assert ok
ok = dill.pickles(oo)
if verbose: print ("%s: %s, %s" % (ok, type(oo), oo))
assert ok
if verbose: print ("")
# frames, generators, and tracebacks (all depend on frame)
def test_frame_related():
g = _g(1)
f = g.gi_frame
e,t = _f()
_is = lambda ok: not ok if dill._dill.IS_PYPY else ok
ok = dill.pickles(f)
if verbose: print ("%s: %s, %s" % (ok, type(f), f))
assert _is(not ok) #XXX: dill fails
ok = dill.pickles(g)
if verbose: print ("%s: %s, %s" % (ok, type(g), g))
assert _is(not ok) #XXX: dill fails
ok = dill.pickles(t)
if verbose: print ("%s: %s, %s" % (ok, type(t), t))
assert not ok #XXX: dill fails
ok = dill.pickles(e)
if verbose: print ("%s: %s, %s" % (ok, type(e), e))
assert ok
if verbose: print ("")
if __name__ == '__main__':
test_frame_related()
test_dict_contents()
test_class()
test_class_descriptors()

@ -0,0 +1,161 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
from dill.source import getsource, getname, _wrap, likely_import
from dill.source import getimportable
import sys
PY3 = sys.version_info[0] >= 3
f = lambda x: x**2
def g(x): return f(x) - x
def h(x):
def g(x): return x
return g(x) - x
class Foo(object):
def bar(self, x):
return x*x+x
_foo = Foo()
def add(x,y):
return x+y
# yes, same as 'f', but things are tricky when it comes to pointers
squared = lambda x:x**2
class Bar:
pass
_bar = Bar()
# inspect.getsourcelines # dill.source.getblocks
def test_getsource():
assert getsource(f) == 'f = lambda x: x**2\n'
assert getsource(g) == 'def g(x): return f(x) - x\n'
assert getsource(h) == 'def h(x):\n def g(x): return x\n return g(x) - x\n'
assert getname(f) == 'f'
assert getname(g) == 'g'
assert getname(h) == 'h'
assert _wrap(f)(4) == 16
assert _wrap(g)(4) == 12
assert _wrap(h)(4) == 0
assert getname(Foo) == 'Foo'
assert getname(Bar) == 'Bar'
assert getsource(Bar) == 'class Bar:\n pass\n'
assert getsource(Foo) == 'class Foo(object):\n def bar(self, x):\n return x*x+x\n'
#XXX: add getsource for _foo, _bar
# test itself
def test_itself():
assert likely_import(likely_import)=='from dill.source import likely_import\n'
# builtin functions and objects
def test_builtin():
if PY3: builtin = 'builtins'
else: builtin = '__builtin__'
assert likely_import(pow) == 'pow\n'
assert likely_import(100) == '100\n'
assert likely_import(True) == 'True\n'
assert likely_import(pow, explicit=True) == 'from %s import pow\n' % builtin
assert likely_import(100, explicit=True) == '100\n'
assert likely_import(True, explicit=True) == 'True\n' if PY3 else 'from %s import True\n' % builtin
# this is kinda BS... you can't import a None
assert likely_import(None) == 'None\n'
assert likely_import(None, explicit=True) == 'None\n'
# other imported functions
def test_imported():
from math import sin
assert likely_import(sin) == 'from math import sin\n'
# interactively defined functions
def test_dynamic():
assert likely_import(add) == 'from %s import add\n' % __name__
# interactive lambdas
assert likely_import(squared) == 'from %s import squared\n' % __name__
# classes and class instances
def test_classes():
try: #XXX: should this be a 'special case'?
from StringIO import StringIO
x = "from StringIO import StringIO\n"
y = x
except ImportError:
from io import BytesIO as StringIO
x = "from io import BytesIO\n"
y = "from _io import BytesIO\n"
s = StringIO()
assert likely_import(StringIO) == x
assert likely_import(s) == y
# interactively defined classes and class instances
assert likely_import(Foo) == 'from %s import Foo\n' % __name__
assert likely_import(_foo) == 'from %s import Foo\n' % __name__
# test getimportable
def test_importable():
assert getimportable(add) == 'from %s import add\n' % __name__
assert getimportable(squared) == 'from %s import squared\n' % __name__
assert getimportable(Foo) == 'from %s import Foo\n' % __name__
assert getimportable(Foo.bar) == 'from %s import bar\n' % __name__
assert getimportable(_foo.bar) == 'from %s import bar\n' % __name__
assert getimportable(None) == 'None\n'
assert getimportable(100) == '100\n'
assert getimportable(add, byname=False) == 'def add(x,y):\n return x+y\n'
assert getimportable(squared, byname=False) == 'squared = lambda x:x**2\n'
assert getimportable(None, byname=False) == 'None\n'
assert getimportable(Bar, byname=False) == 'class Bar:\n pass\n'
assert getimportable(Foo, byname=False) == 'class Foo(object):\n def bar(self, x):\n return x*x+x\n'
assert getimportable(Foo.bar, byname=False) == 'def bar(self, x):\n return x*x+x\n'
assert getimportable(Foo.bar, byname=True) == 'from %s import bar\n' % __name__
assert getimportable(Foo.bar, alias='memo', byname=True) == 'from %s import bar as memo\n' % __name__
assert getimportable(Foo, alias='memo', byname=True) == 'from %s import Foo as memo\n' % __name__
assert getimportable(squared, alias='memo', byname=True) == 'from %s import squared as memo\n' % __name__
assert getimportable(squared, alias='memo', byname=False) == 'memo = squared = lambda x:x**2\n'
assert getimportable(add, alias='memo', byname=False) == 'def add(x,y):\n return x+y\n\nmemo = add\n'
assert getimportable(None, alias='memo', byname=False) == 'memo = None\n'
assert getimportable(100, alias='memo', byname=False) == 'memo = 100\n'
assert getimportable(add, explicit=True) == 'from %s import add\n' % __name__
assert getimportable(squared, explicit=True) == 'from %s import squared\n' % __name__
assert getimportable(Foo, explicit=True) == 'from %s import Foo\n' % __name__
assert getimportable(Foo.bar, explicit=True) == 'from %s import bar\n' % __name__
assert getimportable(_foo.bar, explicit=True) == 'from %s import bar\n' % __name__
assert getimportable(None, explicit=True) == 'None\n'
assert getimportable(100, explicit=True) == '100\n'
def test_numpy():
try:
from numpy import array
x = array([1,2,3])
assert getimportable(x) == 'from numpy import array\narray([1, 2, 3])\n'
assert getimportable(array) == 'from %s import array\n' % array.__module__
assert getimportable(x, byname=False) == 'from numpy import array\narray([1, 2, 3])\n'
assert getimportable(array, byname=False) == 'from %s import array\n' % array.__module__
except ImportError: pass
#NOTE: if before likely_import(pow), will cause pow to throw AssertionError
def test_foo():
assert getimportable(_foo, byname=False).startswith("import dill\nclass Foo(object):\n def bar(self, x):\n return x*x+x\ndill.loads(")
if __name__ == '__main__':
test_getsource()
test_itself()
test_builtin()
test_imported()
test_dynamic()
test_classes()
test_importable()
test_numpy()
test_foo()

@ -0,0 +1,103 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
import sys
from dill.temp import dump, dump_source, dumpIO, dumpIO_source
from dill.temp import load, load_source, loadIO, loadIO_source
WINDOWS = sys.platform[:3] == 'win'
f = lambda x: x**2
x = [1,2,3,4,5]
# source code to tempfile
def test_code_to_tempfile():
if not WINDOWS: #see: https://bugs.python.org/issue14243
pyfile = dump_source(f, alias='_f')
_f = load_source(pyfile)
assert _f(4) == f(4)
# source code to stream
def test_code_to_stream():
pyfile = dumpIO_source(f, alias='_f')
_f = loadIO_source(pyfile)
assert _f(4) == f(4)
# pickle to tempfile
def test_pickle_to_tempfile():
if not WINDOWS: #see: https://bugs.python.org/issue14243
dumpfile = dump(x)
_x = load(dumpfile)
assert _x == x
# pickle to stream
def test_pickle_to_stream():
dumpfile = dumpIO(x)
_x = loadIO(dumpfile)
assert _x == x
### now testing the objects ###
f = lambda x: x**2
def g(x): return f(x) - x
def h(x):
def g(x): return x
return g(x) - x
class Foo(object):
def bar(self, x):
return x*x+x
_foo = Foo()
def add(x,y):
return x+y
# yes, same as 'f', but things are tricky when it comes to pointers
squared = lambda x:x**2
class Bar:
pass
_bar = Bar()
# test function-type objects that take 2 args
def test_two_arg_functions():
for obj in [add]:
pyfile = dumpIO_source(obj, alias='_obj')
_obj = loadIO_source(pyfile)
assert _obj(4,2) == obj(4,2)
# test function-type objects that take 1 arg
def test_one_arg_functions():
for obj in [g, h, squared]:
pyfile = dumpIO_source(obj, alias='_obj')
_obj = loadIO_source(pyfile)
assert _obj(4) == obj(4)
# test instance-type objects
#for obj in [_bar, _foo]:
# pyfile = dumpIO_source(obj, alias='_obj')
# _obj = loadIO_source(pyfile)
# assert type(_obj) == type(obj)
# test the rest of the objects
def test_the_rest():
for obj in [Bar, Foo, Foo.bar, _foo.bar]:
pyfile = dumpIO_source(obj, alias='_obj')
_obj = loadIO_source(pyfile)
assert _obj.__name__ == obj.__name__
if __name__ == '__main__':
test_code_to_tempfile()
test_code_to_stream()
test_pickle_to_tempfile()
test_pickle_to_stream()
test_two_arg_functions()
test_one_arg_functions()
test_the_rest()

@ -0,0 +1,89 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
import dill
dill.settings['recurse'] = True
import weakref
class _class:
def _method(self):
pass
class _class2:
def __call__(self):
pass
class _newclass(object):
def _method(self):
pass
class _newclass2(object):
def __call__(self):
pass
def _function():
pass
def test_weakref():
o = _class()
oc = _class2()
n = _newclass()
nc = _newclass2()
f = _function
z = _class
x = _newclass
r = weakref.ref(o)
dr = weakref.ref(_class())
p = weakref.proxy(o)
dp = weakref.proxy(_class())
c = weakref.proxy(oc)
dc = weakref.proxy(_class2())
m = weakref.ref(n)
dm = weakref.ref(_newclass())
t = weakref.proxy(n)
dt = weakref.proxy(_newclass())
d = weakref.proxy(nc)
dd = weakref.proxy(_newclass2())
fr = weakref.ref(f)
fp = weakref.proxy(f)
#zr = weakref.ref(z) #XXX: weakrefs not allowed for classobj objects
#zp = weakref.proxy(z) #XXX: weakrefs not allowed for classobj objects
xr = weakref.ref(x)
xp = weakref.proxy(x)
objlist = [r,dr,m,dm,fr,xr, p,dp,t,dt, c,dc,d,dd, fp,xp]
#dill.detect.trace(True)
for obj in objlist:
res = dill.detect.errors(obj)
if res:
print ("%s" % res)
#print ("%s:\n %s" % (obj, res))
# else:
# print ("PASS: %s" % obj)
assert not res
def test_dictproxy():
from dill._dill import DictProxyType
try:
m = DictProxyType({"foo": "bar"})
except:
m = type.__dict__
mp = dill.copy(m)
assert mp.items() == m.items()
if __name__ == '__main__':
test_weakref()
from dill._dill import IS_PYPY
if not IS_PYPY:
test_dictproxy()

@ -0,0 +1,48 @@
PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
--------------------------------------------
1. This LICENSE AGREEMENT is between the Python Software Foundation
("PSF"), and the Individual or Organization ("Licensee") accessing and
otherwise using this software ("Python") in source or binary form and
its associated documentation.
2. Subject to the terms and conditions of this License Agreement, PSF
hereby grants Licensee a nonexclusive, royalty-free, world-wide
license to reproduce, analyze, test, perform and/or display publicly,
prepare derivative works, distribute, and otherwise use Python
alone or in any derivative version, provided, however, that PSF's
License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation; All Rights
Reserved" are retained in Python alone or in any derivative version
prepared by Licensee.
3. In the event Licensee prepares a derivative work that is based on
or incorporates Python or any part thereof, and wants to make
the derivative work available to others as provided herein, then
Licensee hereby agrees to include in any such work a brief summary of
the changes made to Python.
4. PSF is making Python available to Licensee on an "AS IS"
basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
INFRINGE ANY THIRD PARTY RIGHTS.
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
6. This License Agreement will automatically terminate upon a material
breach of its terms and conditions.
7. Nothing in this License Agreement shall be deemed to create any
relationship of agency, partnership, or joint venture between PSF and
Licensee. This License Agreement does not grant permission to use PSF
trademarks or trade name in a trademark sense to endorse or promote
products or services of Licensee, or any third party.
8. By copying, installing or otherwise using Python, Licensee
agrees to be bound by the terms and conditions of this License
Agreement.

@ -0,0 +1,21 @@
Metadata-Version: 2.1
Name: futures
Version: 3.1.1
Summary: Backport of the concurrent.futures package from Python 3.2
Home-page: https://github.com/agronholm/pythonfutures
Author: Brian Quinlan
Author-email: brian@sweetapp.com
Maintainer: Alex Gronholm
Maintainer-email: alex.gronholm+pypi@nextday.fi
License: PSF
Platform: UNKNOWN
Classifier: License :: OSI Approved :: Python Software Foundation License
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 2 :: Only
UNKNOWN

@ -0,0 +1,6 @@
futures-3.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
futures-3.1.1.dist-info/LICENSE,sha256=ppi9XUQeShavbJkrjoDL-hJ1XXLZEIVPofsR1N6wBZo,2395
futures-3.1.1.dist-info/METADATA,sha256=4x6xpqUIETthRvn7Z-puOLm5FypL8DdBOkO4f-RWE9k,674
futures-3.1.1.dist-info/RECORD,,
futures-3.1.1.dist-info/WHEEL,sha256=t_MpApv386-8PVts2R6wsTifdIn0vbUDTVv61IbqFC8,92
futures-3.1.1.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1

@ -0,0 +1,5 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.33.3)
Root-Is-Purelib: true
Tag: py3-none-any

@ -0,0 +1,90 @@
Metadata-Version: 2.1
Name: greenlet
Version: 0.4.15
Summary: Lightweight in-process concurrent programming
Home-page: https://github.com/python-greenlet/greenlet
Maintainer: Alexey Borzenkov
Maintainer-email: snaury@gmail.com
License: MIT License
Platform: any
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Programming Language :: C
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.4
Classifier: Programming Language :: Python :: 2.5
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.0
Classifier: Programming Language :: Python :: 3.1
Classifier: Programming Language :: Python :: 3.2
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Libraries :: Python Modules
.. image:: https://secure.travis-ci.org/python-greenlet/greenlet.png
:target: http://travis-ci.org/python-greenlet/greenlet
The greenlet package is a spin-off of Stackless, a version of CPython
that supports micro-threads called "tasklets". Tasklets run
pseudo-concurrently (typically in a single or a few OS-level threads)
and are synchronized with data exchanges on "channels".
A "greenlet", on the other hand, is a still more primitive notion of
micro-thread with no implicit scheduling; coroutines, in other
words. This is useful when you want to control exactly when your code
runs. You can build custom scheduled micro-threads on top of greenlet;
however, it seems that greenlets are useful on their own as a way to
make advanced control flow structures. For example, we can recreate
generators; the difference with Python's own generators is that our
generators can call nested functions and the nested functions can
yield values too. Additionally, you don't need a "yield" keyword. See
the example in tests/test_generator.py.
Greenlets are provided as a C extension module for the regular
unmodified interpreter.
Greenlets are lightweight coroutines for in-process concurrent
programming.
Who is using Greenlet?
======================
There are several libraries that use Greenlet as a more flexible
alternative to Python's built in coroutine support:
- `Concurrence`_
- `Eventlet`_
- `Gevent`_
.. _Concurrence: http://opensource.hyves.org/concurrence/
.. _Eventlet: http://eventlet.net/
.. _Gevent: http://www.gevent.org/
Getting Greenlet
================
The easiest way to get Greenlet is to install it with pip or
easy_install::
pip install greenlet
easy_install greenlet
Source code archives and windows installers are available on the
python package index at https://pypi.python.org/pypi/greenlet
The source code repository is hosted on github:
https://github.com/python-greenlet/greenlet
Documentation is available on readthedocs.org:
https://greenlet.readthedocs.io

@ -0,0 +1,7 @@
../../include/site/python3.6/greenlet/greenlet.h,sha256=SlcS2utGqDJj1KnMDK745yitcJKNUIbAUaFA8rN-4sY,3972
greenlet-0.4.15.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
greenlet-0.4.15.dist-info/METADATA,sha256=QAeWa2K18gQhCDt1FDxaJts5YpJZ7B8ez3wBioeUmDQ,3304
greenlet-0.4.15.dist-info/RECORD,,
greenlet-0.4.15.dist-info/WHEEL,sha256=xq3J6sB2oJqjv0tDC7tGUGvne1fOugw1JUmk86QA7UM,106
greenlet-0.4.15.dist-info/top_level.txt,sha256=YSnRsCRoO61JGlP57o8iKL6rdLWDWuiyKD8ekpWUsDc,9
greenlet.cp36-win_amd64.pyd,sha256=JEgAoI_JxSm30xINTYVDKN9GNWhDtKJZfo2MphzEp3s,28672

@ -0,0 +1,5 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.31.1)
Root-Is-Purelib: false
Tag: cp36-cp36m-win_amd64

@ -0,0 +1,54 @@
#!C:\Users\sgoud\PycharmProjects\EnsoBot\venv\Scripts\python.exe
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
"""
display the reference paths for objects in ``dill.types`` or a .pkl file
Notes:
the generated image is useful in showing the pointer references in
objects that are or can be pickled. Any object in ``dill.objects``
listed in ``dill.load_types(picklable=True, unpicklable=True)`` works.
Examples::
$ get_objgraph FrameType
Image generated as FrameType.png
"""
import dill as pickle
#pickle.debug.trace(True)
#import pickle
# get all objects for testing
from dill import load_types
load_types(pickleable=True,unpickleable=True)
from dill import objects
if __name__ == "__main__":
import sys
if len(sys.argv) != 2:
print ("Please provide exactly one file or type name (e.g. 'IntType')")
msg = "\n"
for objtype in list(objects.keys())[:40]:
msg += objtype + ', '
print (msg + "...")
else:
objtype = str(sys.argv[-1])
try:
obj = objects[objtype]
except KeyError:
obj = pickle.load(open(objtype,'rb'))
import os
objtype = os.path.splitext(objtype)[0]
try:
import objgraph
objgraph.show_refs(obj, filename=objtype+'.png')
except ImportError:
print ("Please install 'objgraph' to view object graphs")
# EOF

@ -0,0 +1,22 @@
#!C:\Users\sgoud\PycharmProjects\EnsoBot\venv\Scripts\python.exe
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
"""
unpickle the contents of a pickled object file
Examples::
$ undill hello.pkl
['hello', 'world']
"""
if __name__ == '__main__':
import sys
import dill
for file in sys.argv[1:]:
print (dill.load(open(file,'rb')))
Loading…
Cancel
Save