How to add custom renames in six? - python

According to the documentation, six supports adding custom renames to six.moves:
six.add_move(item)
Add item to the six.moves mapping. item should be a MovedAttribute or
MovedModule instance.
And:
class six.MovedModule(name, old_mod, new_mod)
Create a mapping for six.moves called name that references different
modules in Python 2 and 3. old_mod is the name of the Python 2 module.
new_mod is the name of the Python 3 module.
However, this code yields an ImportError for me:
from six import add_move, MovedModule
add_move(MovedModule('mock', 'mock', 'unittest.mock'))
from six.moves.mock import MagicMock
When I run it on Python 3.4.2 using six 1.9.0 I get this error:
Traceback (most recent call last):
File "test_six_moves.py", line 2, in <module>
from six.moves.mock import MagicMock
ImportError: No module named 'six.moves.mock'
The builtin moves are working just fine. How do I get this to work?

You can't import the name from within the move. Use:
from __future__ import print_function
from six import add_move, MovedModule
add_move(MovedModule('mock', 'mock', 'unittest.mock'))
from six.moves import mock
print(mock.MagicMock)
This will give you:
# Python 2
<class 'mock.MagicMock'>
# Python 3
<class 'unittest.mock.MagicMock'>
Note that importing from within a move works for the ones that ship with six. For example: from six.moves.configparser import ConfigParser works.
This piece of code (from six.py) is why:
for attr in _moved_attributes:
setattr(_MovedItems, attr.name, attr)
if isinstance(attr, MovedModule):
_importer._add_module(attr, "moves." + attr.name)
In fact, if you ran the following (meddling with private attributes is of course not recommended), your import would work:
import six
mod = six.MovedModule('mock', 'mock', 'unittest.mock')
six.add_move(mod)
six._importer._add_module(mod, "moves." + mod.name)

Related

pytest: how might I simulate non-availability of a pip-installed module? [duplicate]

I'm trying to use a third-party lib (docutils) on Google App Engine and have a problem with this code (in docutils):
try:
import pwd
do stuff
except ImportError:
do other stuff
I want the import to fail, as it will on the actual GAE server, but the problem is that it doesn't fail on my development box (ubuntu). How to make it fail, given that the import is not in my own code?
Even easier than messing with __import__ is just inserting None in the sys.modules dict:
>>> import sys
>>> sys.modules['pwd'] = None
>>> import pwd
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named pwd
In your testing framework, before you cause docutils to be imported, you can perform this setup task:
import __builtin__
self.savimport = __builtin__.__import__
def myimport(name, *a):
if name=='pwd': raise ImportError
return self.savimport(name, *a)
__builtin__.__import__ = myimport
and of course in teardown put things back to normal:
__builtin__.__import__ = self.savimport
Explanation: all import operations go through __builtin__.__import__, and you can reassign that name to have such operations use your own code (alternatives such as import hooks are better for such purposes as performing import from non-filesystem sources, but for purposes such as yours, overriding __builtin__.__import__, as you see above, affords truly simple code).

How to import "gleam" package in Python 3?

I'm tyring to import the "gleam" package in Python 3. I have installed the "gleam" package successfully, but still it showing error.
from wtforms import fields
from ggplot import *
from gleam import Page, panels
class ScatterInput(panels.Inputs):
title = fields.StringField(label="Title of plot:")
yvar = fields.SelectField(label="Y axis",
choices=[("beef", "Beef"),
("pork", "Pork")])
smoother = fields.BooleanField(label="Smoothing Curve")
class ScatterPlot(panels.Plot):
name = "Scatter"
def plot(self, inputs):
p = ggplot(meat, aes(x='date', y=inputs.yvar))
if inputs.smoother:
p = p + stat_smooth(color="blue")
p = p + geom_point() + ggtitle(inputs.title)
return p
class ScatterPage(Page):
input = ScatterInput()
output = ScatterPlot()
ScatterPage.run()
Error:
ModuleNotFoundError - Traceback (most> recent call last) in ()
----> 1 import gleam
C:\pythonNJ\lib\site-packages\gleam__init__.py in ()
5 import os
6 import json
----> 7 import urlparse
8 from collections import namedtuple
9
ModuleNotFoundError: No module named 'urlparse'
I looked for the solution and I found that urlparse has been moved to a new module in python 3, which can be imported as
from urllib.parse import urlparse
And I even imported it, but still when I trying to import "gleam" package it shows error of module "urlparse". Can you suggest me how to bypass it (bypassing import urlparse statement and importing gleam package in Python 3).
I know how to import the urlparse but I don't know how to import the gleam package.
You have two possiblities:
Modify source code yourself as you stated inside gleam package, but it could work incorrectly.
Fall back to version of python it works on - so 2.7 it seems, since the modification you mentioned was done with python 3.0 release. It's stated in docs here.
Just do this to get over it:
from:
import urlparser
to:
import urllib.parse

Python cannot import from another file name not defined

I am trying to import a custom function from another python file but keep getting an error NameError: name 'testme' is not defined. I confirmed that I am importing the file correctly according to this SO post and that the function is top level. What else can I try to fix this?
My main python file is:
import sys
import dbconn
#from dbconn import testme #<----did not work
dev=True
if(dev):
categId='528'
pollIds=[529,530,531]
else:
categId=str(sys.argv[1])
pollIds=[529,530,531]
df=testme(categIds)#callServer(categId,pollIds)
df
if(not categId.isdigit):
print('categ id fail. expected digit got: '+categId)
.....
and dbconn.py:
import pymysql #pip3 install PyMySQL
import pandas as pd
from scipy.stats.stats import pearsonr
from scipy import stats
def testme(categIds):
try:
df=categIds
except Exception as e:
print("broke")
return categIds
Not sure if it makes a difference but I am running the main python file from within a Jupyter notebook, and have a compiled version of dbconn.py in the same directory
In response to the suggestions I tried:
df=dbconn.testme(categIds)
got the error:
module 'dbconn' has no attribute 'testme'
You Have to follow these fox exact import
1)import <package>
2)import <module>
3)from <package> import <module or subpackage or object>
4)from <module> import <object>
in your case, you have tried
from dbconn import testme
you have to use only packages in from section and module in import section
like >>
from testme import dbconn

Import all modules from a package

I have setup the following structure: Python 201: Creating Modules and Packages.
The mymathpackage is available at that link.
When you run the code below:
import sys
sys.path.append('G:\MyPython\Package')
import mymath
print (mymath.add(4,5))
print (mymath.division(4, 2))
print (mymath.multiply(10, 5))
print (mymath.fibonacci(8))
print (mymath.squareroot(48))
Python Version: 3.4
outer __init__.py contents:
from add import add
from divide import division
from multiply import multiply
from subtract import subtract
from adv.fib import fibonacci
from adv.sqrt import squareroot
My goal is to call division,add,subtract, etc, but if I try to call the module I get:
Traceback (most recent call last):
File "G:\MyPython\Package\myscript.py", line 1, in <module>
import mymath
File "G:\MyPython\Package\mymath\__init__.py", line 1, in <module>
from add import add
ImportError: No module named 'add'
Python 3.x has changed import resolution. You must now specify a full relative import if you want to perform a relative import.
from .add import add

Python import using dot notation doesn't work as expected

I recently installed a library in Python 3.3.2. I tried to import a module from it like this: import cx_Freeze.freezer. However, cx_Freeze.freezer is not defined as I would have expected, as shown in IDLE:
>>> ================================ RESTART ================================
>>> import cx_Freeze.freezer
>>> cx_Freeze.freezer
Traceback (most recent call last):
File "<pyshell#9>", line 1, in <module>
cx_Freeze.freezer
AttributeError: 'module' object has no attribute 'freezer'
>>>
The same thing happens in the command line. I think I am misunderstanding what happens when you use import with dot notation; what name does the module get assigned to?
In order to fix this seeming problem, I tried import cx_Freeze.freezer as f after restarting the shell, but that gave the same error as before. Can someone please explain why these import statements aren't giving me access to the module?
cx_Freeze/__init__.py has the following contents:
version = "5.0"
import sys
from cx_Freeze.dist import *
if sys.platform == "win32":
from cx_Freeze.windist import *
elif sys.platform == "darwin":
from cx_Freeze.macdist import *
from cx_Freeze.finder import *
from cx_Freeze.freezer import *
from cx_Freeze.main import *
del dist
del finder
del freezer
The parts important to this question are from cx_Freeze.freezer import * and del freezer. The first of those lines imports everything listed in cx_Freeze.freezer.__all__ directly into the cx_Freeze package, and the second line makes cx_Freeze.freezer not available directly. Thus, you should probably just use cx_Freeze; it contains all the parts of cx_Freeze.freezer designed for external use. If you need cx_Freeze.freezer, perhaps to use some of the private functionality, you can find it in sys.modules:
import sys
freezer = sys.modules['cx_Freeze.freezer']

Categories